cd

125 阅读14分钟

css

1. 两个嵌套div,外层div宽度500px,内层div宽度20%,要求把内层div设置成正方形

<div class="outer">
  <div class="inner"></div>
</div>

.outer {
  width: 500px; /*0 外层 div 宽度固定为 500px */
  height: auto; /*0 可以根据内容自动调整高度 */
  background-color: lightgray; /*0 用于区分外层 div */
}
.inner {
  width: 20%; /* 内层 div 宽度为外层的 20% */
  padding-top: 20%; /* 通过 padding-top 来设置高度为宽度的 100%,即实现正方形 */
  background-color: lightblue; /*0 用于区分内层 div */
}
 
/* 
高度的实现 通过 padding-top: 20%,这是因为在 CSS 中,padding-top 是相对于宽度计算的,
因此设置 padding-top 为 20% 会使得高度和宽度相等,从而实现正方形效果。
*/

2. 一个div嵌套三个div 外层div为flex布局,实现内层俩个div靠左 第三个div靠右

<div class="outer">
  <div class="left1">Left 1</div>
  <div class="left2">Left 2</div>
  <div class="right">Right</div>
</div>
 
.outer {
  display: flex; /* 设置外层 div 为 flex 布局 */
}
.right {
  margin-left: auto; /* 将右侧的 div 推到最右边 */
}

3. 用 css 实现如下的多列布局(类似九宫格,右下角为空)效果:父元素宽度自适应所在容器宽度,高度由子元素撑开, 有不定数量的直接子元素(可以用8个演示),每一行排3 个子元素,子元素之间的水平、垂直间距为 10px ,子元素的宽度自适应父元素的宽度((父元素宽度 - 10px * 2) / 3),子元素的高度与自身的宽度成正比(比如 2:1)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>九宫格布局</title>
  <style>
    .container {
      display: grid;
      grid-template-columns: repeat(3, 1fr); /* 三列 */
      gap: 10px; /* 间距 */
      /* width: 300px; 父元素宽度 */
      margin: 0 auto; /* 居中 */
    }

    .item {
      background-color: #69c; /* 子元素背景色 */
      border: 1px solid #000;
      aspect-ratio: 1 / 2; /* 宽度与高度比例为1:2 */
    }

    /* 去掉右下角 */
    /* .item:nth-child(9) {
      display: none;
    } */
  </style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <!-- <div class="item">9</div> -->
    <!-- 第九个元素为空 -->
  </div>
</body>
</html>

4.画一个表盘,实现分针和秒钟的旋转动画

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>表盘动画</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="clock">
    <div class="dial">
      <div class="hand second-hand"></div>
      <div class="hand minute-hand"></div>
    </div>
  </div>
  <script src="script.js"></script>
</body>
</html>
 
 
/* styles.css */
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background: #f5f5f5;
}
 
.clock {
  width: 200px;
  height: 200px;
  border: 8px solid #333;
  border-radius: 50%;
  position: relative;
  background: white;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}
 
.dial {
  position: relative;
  width: 100%;
  height: 100%;
}
 
.hand {
  position: absolute;
  bottom: 50%;
  left: 50%;
  transform-origin: bottom;
  transform: rotate(0deg);
  transition: transform 0.1s ease-in-out;
}
 
.second-hand {
  width: 2px;
  height: 90px;
  background: red;
  z-index: 2;
}
 
.minute-hand {
  width: 4px;
  height: 70px;
  background: black;
  z-index: 1;
}
 
 
// script.js
function setClock() {
  const now = new Date();
  // 计算当前秒和分的角度
  const seconds = now.getSeconds();
  const minutes = now.getMinutes();
  const secondDegree = (seconds / 60) * 360;
  const minuteDegree = (minutes / 60) * 360 + (seconds / 60) * 6; // 添加秒钟影响
 
  // 更新样式
  const secondHand = document.querySelector('.second-hand');
  const minuteHand = document.querySelector('.minute-hand');
  secondHand.style.transform = `rotate(${secondDegree}deg)`;
  minuteHand.style.transform = `rotate(${minuteDegree}deg)`;
}
 
// 每秒更新一次
setInterval(setClock, 1000);
 
// 初始设置
setClock();

react

1. 编写一个倒计时ui组件 组件有俩个参数:截止时间deadline和时间到期时执行的回调函数cb

import React, { useEffect, useState } from 'react';
 
const Countdown = ({ deadline, cb }) => {
  const [timeLeft, setTimeLeft] = useState(calculateTimeLeft(deadline));
 
  // 计算剩余时间的函数
  function calculateTimeLeft(deadline) {
    const difference = new Date(deadline) - new Date();
    if (difference > 0) {
      return {
        hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
        minutes: Math.floor((difference / 1000 / 60) % 60),
        seconds: Math.floor((difference / 1000) % 60),
      };
    } else {
      return null;  // 如果时间到了,返回null
    }
  }
 
  // 倒计时更新逻辑
  useEffect(() => {
    const timer = setInterval(() => {
      const newTimeLeft = calculateTimeLeft(deadline);
      setTimeLeft(newTimeLeft);
      if (!newTimeLeft) {
        clearInterval(timer); // 清除计时器
        if (cb) cb(); // 执行回调函数
      }
    }, 1000);
 
    return () => clearInterval(timer); // 清除副作用
  }, [deadline, cb]);
 
  // 倒计时的 UI 展示
  return (
    <div>
      {timeLeft ? (
        <div>
          <span>{timeLeft.hours}h </span>
          <span>{timeLeft.minutes}m </span>
          <span>{timeLeft.seconds}s</span>
        </div>
      ) : (
        <div>Time's up!</div>
      )}
    </div>
  );
};
 
export default Countdown;

2.实现useFetch

import { useState, useEffect, useCallback } from 'react';
 
function useFetch(url, options = {}) {
    const [data, setData] = useState(null);   // 存储请求的数据
    const [loading, setLoading] = useState(true); // 请求状态:加载中
    const [error, setError] = useState(null);    // 存储错误信息
    const [shouldFetch, setShouldFetch] = useState(true); // 控制是否进行请求
 
    // fetchData 用于发起请求
    const fetchData = useCallback(async () => {
        setLoading(true);   // 请求开始,设置加载状态
        setError(null);      // 清空之前的错误
        try {
            const response = await fetch(url, options);  // 发起 fetch 请求
            if (!response.ok) { // 检查响应状态
                throw new Error(`HTTP Error! Status: ${response.status}`);
            }
            const result = await response.json();  // 假设返回的是 JSON 格式数据
            setData(result);  // 将结果存储到 data 中
        } catch (error) {
            setError(error.message);  // 捕获错误并存储
        } finally {
            setLoading(false); // 请求完成,更新加载状态
        }
    }, [url, options]);
 
    // 使用 useEffect 来控制发起请求
    useEffect(() => {
        if (shouldFetch) {
            fetchData(); // 如果 shouldFetch 为 true,发起请求
            setShouldFetch(false); // 请求完成后,重置 shouldFetch
        }
    }, [url, options, shouldFetch, fetchData]);
 
    // refetch 方法,用于手动重新发起请求
    const refetch = () => {
        setShouldFetch(true);  // 设置 shouldFetch 为 true,触发请求
    };
 
    return { data, loading, error, refetch }; // 返回请求状态和 refetch 方法
}
 
export default useFetch;

class

1.实现一个符合LRU(最近最少使用) 缓存的类

class LRUCache {
    constructor(capacity) {
        this.capacity = capacity;  // 缓存的容量
        this.cache = new Map();  // 使用 Map 存储缓存项,保证 O(1) 的查找、删除、插入
    }
 
    // 获取缓存项
    get(key) {
        if (this.cache.has(key)) {
            // 如果缓存中存在该 key,将其移到最近使用的位置
            const value = this.cache.get(key);
            this.cache.delete(key);  // 先删除,再重新插入(确保更新顺序)
            this.cache.set(key, value);  // 重新插入到 Map 的末尾
            return value;
        }
        return -1;  // 如果 key 不存在,返回 -1
    }
 
    // 插入或更新缓存项
    put(key, value) {
        if (this.cache.has(key)) {
            // 如果缓存中存在该 key,先删除旧的值
            this.cache.delete(key);
        } else if (this.cache.size >= this.capacity) {
            // 如果缓存已满,删除最久未使用的元素
            // Map 中的第一个元素是最久未使用的元素
            this.cache.delete(this.cache.keys().next().value);
        }
        // 插入新的键值对
        this.cache.set(key, value);
    }
}
 
// 测试用例
const lruCache = new LRUCache(3);  // 初始化缓存,容量为 3
lruCache.put(1, 1);  // 缓存是 {1=1}
lruCache.put(2, 2);  // 缓存是 {1=1, 2=2}
lruCache.put(3, 3);  // 缓存是 {1=1, 2=2, 3=3}
console.log(lruCache.get(1));  // 返回 1,缓存是 {1=1, 2=2, 3=3}
lruCache.put(4, 4);  // 该操作会导致 2 被移除,缓存是 {1=1, 3=3, 4=4}
console.log(lruCache.get(2));  // 返回 -1 (未找到)
console.log(lruCache.get(3));  // 返回 3
console.log(lruCache.get(4));  // 返回 4

2、写个工具函数对promise封装,输入一个promise a 返回一个promise b 如果1秒内a 没有结果 则在1秒时抛出错误,否则b和a等价

function withTimeout(promise, timeout = 1000) {
  return new Promise((resolve, reject) => {
    // 创建一个定时器来在超时时间后抛出错误
    const timer = setTimeout(() => {
      reject(new Error('Operation timed out'));
    }, timeout);
 
    // 处理传入的 promise
    promise
      .then((result) => {
        clearTimeout(timer);  // 在 Promise 解析后清除定时器
        resolve(result);
      })
      .catch((error) => {
        clearTimeout(timer);  // 如果 Promise 被拒绝,清除定时器
        reject(error);
      });
  });
}
 
// 使用示例
const promiseA = new Promise((resolve) => {
  setTimeout(() => {
    resolve('Result from promiseA');
  }, 500);  // 500ms 后 resolve
});
 
withTimeout(promiseA, 1000)
  .then((result) => {
    console.log(result);  // 如果在 1 秒内 resolve, 输出结果
  })
  .catch((error) => {
    console.error(error);  // 超时或 promiseA 拒绝时输出错误
  });

3、实现一个带有并发限制的异步调度器 Scheduler,包含入队 出队 运行和暂停功能

class Scheduler {
  constructor(maxConcurrency) {
    this.maxConcurrency = maxConcurrency; // 最大并发数
    this.queue = []; // 任务队列
    this.runningTasks = 0; // 当前运行中的任务数
    this.paused = false; // 调度器是否处于暂停状态
  }

  // 入队任务
  enqueue(task) {
    return new Promise((resolve, reject) => {
      const wrapperTask = async () => {
        if (this.paused) {
          // 如果暂停,则等待继续
          await new Promise((res) => {
            this.resumeCallback = res;
          });
        }
        try {
          this.runningTasks++; // 增加运行中的任务数
          const result = await task(); // 执行任务
          resolve(result); // 任务完成后,标记成功
        } catch (error) {
          reject(error); // 如果任务出错,标记失败
        } finally {
          this.runningTasks--; // 减少运行中的任务数
          this.run(); // 检查是否需要运行下一个任务
        }
      };

      this.queue.push(wrapperTask); // 将任务加入队列
      this.run(); // 立即尝试运行任务
    });
  }

  // 出队任务(手动移除)
  dequeue(task) {
    const index = this.queue.indexOf(task);
    if (index > -1) {
      this.queue.splice(index, 1); // 从队列中移除任务
    }
  }

  // 运行任务
  run() {
    if (this.paused) return; // 如果暂停,不运行任务

    while (this.runningTasks < this.maxConcurrency && this.queue.length > 0) {
      const task = this.queue.shift(); // 从队列中取出一个任务
      task(); // 执行任务
    }
  }

  // 暂停
  pause() {
    this.paused = true;
  }

  // 继续运行
  resume() {
    this.paused = false;
    if (this.resumeCallback) {
      this.resumeCallback(); // 唤醒暂停的任务
      this.resumeCallback = null;
    }
    this.run(); // 继续运行任务
  }
}

const scheduler = new Scheduler(2); // 最大并发数为 2

const timeout = (time) =>
  new Promise((resolve) => setTimeout(resolve, time));

// 模拟任务函数
const createTask = (id, delay) => async () => {
  console.log(`Task ${id} started`);
  await timeout(delay);
  console.log(`Task ${id} completed`);
};

// 入队任务
scheduler.enqueue(createTask(1, 3000));
scheduler.enqueue(createTask(2, 2000));
scheduler.enqueue(createTask(3, 1000));
scheduler.enqueue(createTask(4, 1500));

// 暂停和继续
setTimeout(() => {
  console.log("Pausing scheduler...");
  scheduler.pause();
}, 1000);

setTimeout(() => {
  console.log("Resuming scheduler...");
  scheduler.resume();
}, 5000);

4、链式调用实现:3秒后打印red,接着打印参数b的值,接着打印yellow

class Task {
  constructor() {
    this.taskQueue = []; // 任务队列
  }
 
  // 添加任务的方法,支持传递参数
  add(task, ...args) {
    this.taskQueue.push(() => new Promise(resolve => task(resolve, ...args)));
    return this; // 链式调用
  }
 
  // 运行任务队列的方法
  run() {
    // 使用 reduce 链式执行任务
    this.taskQueue.reduce((prevTask, currTask) => {
      return prevTask.then(() => currTask());
    }, Promise.resolve());
  }
}
 
// 定义 task1、task2、task3
function task1(next) {
  setTimeout(() => {
    console.log('red');
    next(); // 调用 next 以触发下一个任务
  }, 3000);
}
 
function task2(next, b) {
  setTimeout(() => {
    console.log(b); // 打印参数 b
    next(); // 调用 next 以触发下一个任务
  }, 3000);
}
 
function task3(next) {
  setTimeout(() => {
    console.log('yellow');
    next(); // 调用 next 以触发下一个任务
  }, 2000);
}
 
// 使用 Task 类来添加和执行任务
const task = new Task();
task.add(task1).add(task2, 1).add(task3).run();

实现Monkey,返回的对象提供eat和sleep两个函数,支持链式调用。具体调用方式如下所示:Monkey('Alan').eat('Banana').sleep(4).eat('Apple').sleep(5).eat('Pear')

class Monkey {
  constructor(name) {
    this.name = name;
    this.queue = []; // 异步任务队列

    console.log(`my name is ${name}`);
    // 开始执行任务队列
    setTimeout(() => {
      this.runQueue();
    }, 0);
  }

  eat(food) {
    // 将 eat 任务推入队列
    this.queue.push(() => {
      console.log(`I eat ${food}`);
      return Promise.resolve();
    });
    return this; // 返回当前实例以支持链式调用
  }

  sleep(seconds) {
    // 将 sleep 任务推入队列
    this.queue.push(() => {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(`// 等待 ${seconds} s`);
          resolve();
        }, seconds * 1000);
      });
    });
    return this; // 返回当前实例以支持链式调用
  }

  async runQueue() {
    // 按顺序执行队列中的任务
    for (const task of this.queue) {
      await task();
    }
  }
}

// 测试代码
new Monkey('Alan').eat('Banana').sleep(4).eat('Apple').sleep(5).eat('Pear');

5.发布订阅类EventEmitter

class EventEmitter {
  constructor() {
    this.list = {}
  }
  // 订阅事件(subscribe)
  on(event, callback) {
    if (!this.list[event]) {
      this.list[event] = []
    }
    this.list[event].push(callback)
  }
  // 发布事件(publish)
  emit(event, ...args) {
    if (this.list[event]) {
      this.list[event].forEach(fn => {
        fn.apply(this, args)
      });
    }
  }
  // 取消订阅(unsubscribe)
  off(event, callback) {
    if (this.list[event] && callback) {
      this.list[event] = this.list[event].filter(fn => fn !== callback)
    }
  }
  // once方法用于仅订阅一次事件,即回调函数只会被执行一次
  once(event, callback) {
    const onceCallback = (...args) => {
      callback.apply(this, args)
      this.off(event, onceCallback)
    }
    this.on(event, onceCallback)
  }
}
 
function hello(...data) {
  console.log('hello' + data);
}
 
const emitter = new EventEmitter()
// 使用 once 方法订阅事件,回调函数只会被执行一次
emitter.once('onSell', hello)
// 触发事件,只会执行一次回调函数
emitter.emit('onSell', '1', '2', '3')
emitter.emit('onSell', '1', '2', '3') 

6.有一种花, 两种鸟, 花定时开放,鸟看到花开会叫, 鸟的叫声不一样

class EventBus {
    constructor(){
        this.list = {}
    }
    on(fnName,fn){
        if(!this.list[fnName]) this.list[fnName] = []
        this.list[fnName].push(fn)
    }
    emit(fnName,...args){
        if(this.list[fnName]){
            this.list[fnName].forEach(fn => {
                fn.apply(this,args)
            });
        }
    }
}
const events = new EventBus()
// 发布者
class Flower{
    constructor(){}
    open(delay){
        setTimeout(()=>{
            events.emit('flowerOpen')
        }, delay)
    }
}
// 订阅者
class Bird{
    constructor(name,sound){
        this.name = name
        this.sound = sound
        events.on('flowerOpen', this.makeSound.bind(this))
 
    }
    makeSound(){
        console.log(this.name, this.sound)
    }
}
 
// 测试
const myFlower = new Flower()
const bird1 = new Bird('A', '布谷布谷')
const bird2 = new Bird('B', '叽叽喳喳')
myFlower.open(1000) 

JS

1.用链表实现一个队列js实现

class Node {
  constructor(value) {
    this.value = value;    // 节点的值
    this.next = null;      // 指向下一个节点的指针
  }
}
 
class Queue {
  constructor() {
    this.front = null;  // 队列的头部(出队的一端)
    this.rear = null;   // 队列的尾部(入队的一端)
    this.length = 0;    // 队列中的元素数量
  }
 
  // 入队操作:在队列末尾添加元素
  enqueue(value) {
    const newNode = new Node(value);  // 创建一个新的节点
    if (this.rear) {
      this.rear.next = newNode;       // 将新节点添加到尾部
    }
    this.rear = newNode;              // 更新尾部为新节点
    if (!this.front) {
      this.front = newNode;           // 如果队列为空,头部也指向新节点
    }
    this.length++;                    // 增加队列的长度
  }
 
  // 出队操作:移除并返回队列头部的元素
  dequeue() {
    if (!this.front) {
      return null;  // 如果队列为空,返回 null
    }
    const removedNode = this.front;   // 保存当前头部节点
    this.front = this.front.next;     // 将头部更新为下一个节点
    if (!this.front) {
      this.rear = null;  // 如果移除后队列为空,尾部也要置为 null
    }
    this.length--;  // 减少队列长度
    return removedNode.value;  // 返回移除的节点的值
  }
 
  // 查看队列头部元素
  peek() {
    return this.front ? this.front.value : null;  // 如果队列为空,返回 null
  }
 
  // 判断队列是否为空
  isEmpty() {
    return this.length === 0;
  }
 
  // 获取队列长度
  size() {
    return this.length;
  }
}
 
 
const queue = new Queue();
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
 
console.log(queue.peek());   // 输出 10
console.log(queue.dequeue()); // 输出 10
console.log(queue.size());    // 输出 2
console.log(queue.isEmpty()); // 输出 false

2. 在字符串中找出最大数字及其变式

// 1.基本实现
function findLargestNumber(str) {
  // 使用正则表达式匹配字符串中的所有数字
  const numbers = str.match(/\d+/g);
  
  // 如果没有匹配到数字,返回 null
  if (!numbers) return null;
  
  // 使用 Math.max 找出最大值
  const maxNumber = Math.max(...numbers.map(Number));
  
  return maxNumber;
}
 
// 2 不用正则,考虑字符串里无数字情况
function findLargestNumber(str) {
  let maxNumber = -Infinity;  // 初始化为负无穷大,方便处理没有数字的情况
  let currentNumber = 0;
  let inNumber = false; // 标记是否在处理数字
  let hasNumber = false; // 标记是否有遇到数字
 
  for (let i = 0; i < str.length; i++) {
    const char = str[i];
 
    // 如果字符是数字
    if (char >= '0' && char <= '9') {
      currentNumber = currentNumber * 10 + (char - '0'); // 构建当前数字
      inNumber = true;
      hasNumber = true;  // 标记已经遇到了数字
    } else {
      // 遇到非数字字符时,检查当前数字并更新最大值
      if (inNumber) {
        maxNumber = Math.max(maxNumber, currentNumber);
        currentNumber = 0; // 重置当前数字
        inNumber = false;
      }
    }
  }
 
  // 处理最后一个数字
  if (inNumber) {
    maxNumber = Math.max(maxNumber, currentNumber);
  }
 
  // 如果没有找到任何数字,返回 null
  return hasNumber ? maxNumber : null;
}
 
// 3.允许str中有负数
function findLargestNumber(str) {
  let maxNumber = -Infinity;  // 初始化为负无穷大
  let currentNumber = 0;
  let sign = 1;  // 用于标记当前数字的正负
  let inNumber = false;  // 标记是否在处理数字
  let hasNumber = false;  // 标记是否遇到了数字
 
  for (let i = 0; i < str.length; i++) {
    const char = str[i];
 
    // 检查负号,负号后面必须跟数字
    if (char === '-' && i + 1 < str.length && str[i + 1] >= '0' && str[i + 1] <= '9') {
      sign = -1;
    } 
    // 如果是数字,构建当前数字
    else if (char >= '0' && char <= '9') {
      currentNumber = currentNumber * 10 + (char - '0');
      inNumber = true;
      hasNumber = true;
    } 
    // 非数字或负号,处理当前数字
    else if (inNumber) {
      maxNumber = Math.max(maxNumber, currentNumber * sign);
      currentNumber = 0;
      inNumber = false;
      sign = 1;  // 重置正负标记
    }
  }
 
  // 处理最后一个数字
  if (inNumber) {
    maxNumber = Math.max(maxNumber, currentNumber * sign);
  }
 
  // 如果没有数字,返回 null
  return hasNumber ? maxNumber : null;
}

3.单链表判断是否有环及其变式

// 1.快慢指针实现
function hasCycle(head) {
    let slow = head;
    let fast = head;
 
    while (fast !== null && fast.next !== null) {
        slow = slow.next;         // 慢指针每次走一步
        fast = fast.next.next;    // 快指针每次走两步
        
        if (slow === fast) {      // 快慢指针相遇,说明有环
            return true;
        }
    }
 
    return false;  // 快指针遇到null,说明没有环
}
 
// 2.怎么确定环的长度
function cycleLength(head) {
    let slow = head;
    let fast = head;
 
    // 先找到快慢指针相遇的地方
    while (fast !== null && fast.next !== null) {
        slow = slow.next;
        fast = fast.next.next;
 
        if (slow === fast) {
            // 计算环的长度
            let length = 0;
            do {
                fast = fast.next;
                length++;
            } while (slow !== fast);
            return length;
        }
    }
 
    return 0;  // 没有环
}
 
// 3.怎么确定入环点
// 相遇时,快指针已经走了比慢指针多 n 圈,即从起点走到环的入口与从相遇点走到环的入口需要的步数相同。因此将慢指针重置到链表头部,与快指针一起一步步移动,最终会在环的入口节点相遇。
 
function findCycleStart(head) {
    let slow = head;
    let fast = head;
 
    // 首先通过快慢指针找到相遇点
    while (fast !== null && fast.next !== null) {
        slow = slow.next;
        fast = fast.next.next;
 
        if (slow === fast) {
            // 找到相遇点后,将慢指针移回到起点
            slow = head;
 
            // 两个指针每次走一步,相遇点即为入环点
            while (slow !== fast) {
                slow = slow.next;
                fast = fast.next;
            }
 
            return slow; // 入环点
        }
    }
 
    return null; // 没有环
}

4.实现函数柯里化

const curry = (fn) => {
    return function curried(...args){
        if(args.length>=fn.length){
            return fn(...args)
        } else {
            return function(...args2){
                return curried(...args, ...args2)
            }
        }
    }
}

5.给一个嵌套对象查找其属性路径对应的值用数组形式返回

function findNestedProperties(obj) {
  const result = [];
 
  function recurse(currentObj, currentPath) {
    for (const key in currentObj) {
      if (currentObj.hasOwnProperty(key)) {
        const newPath = currentPath ? `${currentPath}${key}` : key;
 
        // 检查是否为基本数据类型或数组
        if (typeof currentObj[key] !== 'object' || currentObj[key] === null || Array.isArray(currentObj[key])) {
          result.push({ key: newPath, value: currentObj[key] });
        } else {
          // 如果是对象,则递归
          recurse(currentObj[key], newPath);
        }
      }
    }
  }
 
  recurse(obj, '');
  return result;
}

6.实现一个对象浅比较

function shallowEqual(obj1, obj2) {
  // 如果引用相同,直接返回 true
  if (obj1 === obj2) return true;
 
  // 如果其中一个是 null 或 undefined,另一个不是,直接返回 false
  if (obj1 == null || obj2 == null) return false;
 
  // 获取对象的属性名称
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
 
  // 如果两个对象的属性数量不同,直接返回 false
  if (keys1.length !== keys2.length) return false;
 
  // 遍历属性,比较每个属性的值
  for (let key of keys1) {
    // 使用严格相等比较值
    if (obj1[key] !== obj2[key]) {
      return false;
    }
  }
 
  return true;
}
 
// 示例用法
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
const obj3 = { a: 1, b: 3 };
 
console.log(shallowEqual(obj1, obj2));  // true
console.log(shallowEqual(obj1, obj3));  // false

7.兔子吃草

// 找到有毒的草堆,需要多少只兔子
function findPoisonousGrass(numGrass, poisonedIndex) {
  // 计算需要多少位二进制来表示所有草堆的编号
  const binaryLength = Math.ceil(Math.log2(numGrass));  // 需要的二进制位数
 
  // 将有毒草堆编号转换为二进制字符串,补齐到 binaryLength 位
  const poisonedBinary = poisonedIndex.toString(2).padStart(binaryLength, '0');
 
  // 计算需要死亡的兔子的数量
  let deadRabbitCount = 0;
  for (let i = 0; i < poisonedBinary.length; i++) {
    if (poisonedBinary[i] === '1') {
      deadRabbitCount++;
    }
  }
 
  // 返回死亡兔子的数量
  return deadRabbitCount;
}
 
// 假设毒草是第 678 堆草
const numGrass = 1000;
const poisonedIndex = 678;  // 假设第 678 堆草是有毒的
const deadRabbitCount = findPoisonousGrass(numGrass, poisonedIndex);
console.log(`The number of rabbits that need to die: ${deadRabbitCount}`);
 
 
 
// 哪几只兔子会死
function findPoisonousGrass(numGrass, poisonedIndex) {
  // 计算需要多少位二进制来表示所有草堆的编号
  const binaryLength = Math.ceil(Math.log2(numGrass));  // 需要的二进制位数
 
  // 将有毒草堆编号转换为二进制字符串,补齐到 binaryLength 位
  const poisonedBinary = poisonedIndex.toString(2).padStart(binaryLength, '0');
 
  
  // 计算哪些兔子需要死
  const rabbitsToDie = [];
  for (let i = 0; i < binaryLength; i++) {
    if (poisonedBinary[i] === '1') {
      rabbitsToDie.push(i + 1); // 兔子的编号从1开始
    }
  }
 
  console.log(`The rabbits that need to die: ${rabbitsToDie.join(', ')}`);
}
 
// 假设毒草是第 678 堆草
const numGrass = 1000;
const poisonedIndex = 678;
findPoisonousGrass(numGrass, poisonedIndex);

8.分页效果 [1],2,3...99,100   1,2,[3]4,...99,100  1,...,4,[5],6,...99,100

const generatePageNumbers = () => {
    const pages = [];
    
    // Always show the first page
    pages.push(1);
 
    // Add "..." if there is a gap between first page and current page
    if (currentPage > 3) {
      pages.push('...');
    }
 
    // Show two pages before the current page, but don't go below 1
    for (let i = Math.max(currentPage - 2, 2); i < currentPage; i++) {
      pages.push(i);
    }
 
    // Show the current page
    pages.push(currentPage);
 
    // Show two pages after the current page, but don't go beyond totalPages
    for (let i = currentPage + 1; i <= Math.min(currentPage + 2, totalPages - 1); i++) {
      pages.push(i);
    }
 
    // Add "..." if there is a gap between last page and current page
    if (currentPage < totalPages - 2) {
      pages.push('...');
    }
 
    // Always show the last page
    if (totalPages > 1) {
      pages.push(totalPages);
    }
 
    return pages;
  };

9.求子数组的最大和、最大积

// 子数组最大和
function maxSubArray(nums) {
    let maxSum = nums[0];  // 初始化最大子数组和
    let currentSum = nums[0];  // 当前子数组和
    let start = 0, end = 0;  // 最大子数组的起始和结束索引
    let tempStart = 0;  // 临时记录当前子数组的起始索引
    
    for (let i = 1; i < nums.length; i++) {
        // 如果当前元素和当前和之和大于当前元素,则继续累加,否则重新开始新子数组
        if (currentSum + nums[i] > nums[i]) {
            currentSum += nums[i];
        } else {
            currentSum = nums[i];
            tempStart = i;  // 重新开始一个新子数组
        }
        
        // 更新最大和和子数组的起始和结束位置
        if (currentSum > maxSum) {
            maxSum = currentSum;
            start = tempStart;
            end = i;
        }
    }
    
    // 提取最大子数组
    const subarray = nums.slice(start, end + 1);
    
    return { maxSum, subarray };
}
 
// 示例
const nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
const result = maxSubArray(nums);
console.log("最大子数组和:", result.maxSum);
console.log("最大子数组:", result.subarray);
 
 
 
// 子数组最大积1
function maxProductSubArray(nums) {
    let maxProduct = nums[0];  // 当前子数组的最大积
    let minProduct = nums[0];  // 当前子数组的最小积
    let result = nums[0];      // 记录结果,最终返回的最大积
 
    for (let i = 1; i < nums.length; i++) {
        // 如果当前数是负数,交换最大积和最小积
        if (nums[i] < 0) {
            [maxProduct, minProduct] = [minProduct, maxProduct];
        }
 
        // 更新最大积和最小积
        maxProduct = Math.max(nums[i], maxProduct * nums[i]);
        minProduct = Math.min(nums[i], minProduct * nums[i]);
 
        // 更新结果
        result = Math.max(result, maxProduct);
    }
 
    return result;
}
 
// 示例
const nums = [2, 3, -2, 4];
const result = maxProductSubArray(nums);
console.log("最大子数组积:", result);
 
// 动态规划法求积
class Solution {
    maxProduct(nums) {
        if (nums.length === 0) return 0;
        
        let maxStack = [nums[0]];
        let minStack = [nums[0]];
        
        for (let i = 1; i < nums.length; i++) {
            const n1 = maxStack[maxStack.length - 1] * nums[i];
            const n2 = minStack[minStack.length - 1] * nums[i];
            const n3 = nums[i];
            
            maxStack.push(Math.max(n1, n2, n3));
            minStack.push(Math.min(n1, n2, n3));
        }
        
        return Math.max(...maxStack);
    }
}
 
// 示例
const solution = new Solution();
const nums = [2, 3, -2, 4];
const result = solution.maxProduct(nums);
console.log(result);  // 输出 6

10.模板引擎(模板中有空格)

function templateEngine(template, data) {
  return template.replace(/{{\s*(\w+)\s*}}/g, (_, key) => {
    // 从数据中获取对应值
    const value = data[key.trim()];
    // 如果存在值,替换占位符;否则返回占位符本身
    return value !== undefined ? value : `{{${key}}}`;
  });
}
 
// 示例用法
const template = `
  Hello, {{ name }}!
  Today is {{  day  }}.
  Weather: {{weather}}
`;
 
const data = {
  name: "Alice",
  day: "Monday",
  weather: "Sunny"
};
 
console.log(templateEngine(template, data));

给定一组存在 ${a.b.c}形式占位符的字符串和一组数据,将字符串中的占位替换成真实的数据并输出

const data = { 
  date: '2022年9月', 
  model: 'iPhone 14', 
  price: { startPrice: 5999 } 
};

const tpl = '苹果公司在 ${date} 发布了全新的 ${model} 系列手机,起售价格 ${price.startPrice} 元';

// 模板解析函数
const getTpl = (data, tpl) => {
  return tpl.replace(/\$\{([\w.]+)\}/g, (_, path) => {
    // 使用递归解析路径
    return path.split('.').reduce((res, key) => res[key], data) || '';
  });
};

// 调用并打印结果
const result = getTpl(data, tpl);
console.log(result);

  1. 实现两数近似和
/**
 * 找到数组中所有两个数的和最接近目标值的数对,并返回它们的下标
 * @param {number[]} nums - 整数数组
 * @param {number} target - 目标值
 * @return {number[][]} - 所有最接近目标值的数对的下标
 */
function twoSumClosest(nums, target) {
    if (nums.length < 2) {
        throw new Error("数组中至少需要两个元素");
    }
 
    // 创建一个包含元素值和原始下标的数组
    const numsWithIndices = nums.map((num, index) => ({ num, index }));
 
    // 对新的数组按照元素值进行排序
    numsWithIndices.sort((a, b) => a.num - b.num);
 
    let left = 0;
    let right = numsWithIndices.length - 1;
    let closestSum = numsWithIndices[left].num + numsWithIndices[right].num;
    let minDiff = Math.abs(closestSum - target);
    let result = [[numsWithIndices[left].index, numsWithIndices[right].index]];
 
    while (left < right) {
        const currentSum = numsWithIndices[left].num + numsWithIndices[right].num;
        const currentDiff = Math.abs(currentSum - target);
 
        if (currentDiff < minDiff) {
            // 找到新的更接近的和,清空之前的结果并添加当前对
            closestSum = currentSum;
            minDiff = currentDiff;
            result = [[numsWithIndices[left].index, numsWithIndices[right].index]];
        } else if (currentDiff === minDiff) {
            // 找到相同最小差值的和,添加到结果中
            const newPair = [numsWithIndices[left].index, numsWithIndices[right].index];
            // 确保小的下标在前,避免 [1,0] 和 [0,1] 这样的重复
            newPair.sort((a, b) => a - b);
            // 检查是否已经存在该对
            const lastPair = result[result.length - 1];
            if (!(lastPair[0] === newPair[0] && lastPair[1] === newPair[1])) {
                result.push(newPair);
            }
        }
 
        // 根据当前和与目标值的比较,移动指针
        if (currentSum < target) {
            left++;
        } else if (currentSum > target) {
            right--;
        } else {
            // 当 currentSum === target 时,同时移动两个指针以查找其他可能的数对
            left++;
            right--;
        }
    }
 
    return result;
}
 
// 示例用法
const nums1 = [-1, 2, 1, -4];
const target1 = 1;
const result1 = twoSumClosest(nums1, target1);
console.log(`最接近目标 ${target1} 的数对的下标是:`, result1); 
// 输出: 最接近目标 1 的数对的下标是: [ [ 0, 1 ] ]
 
const nums2 = [-1, 2, 1, -4, 3, 0];
const target2 = 1;
const result2 = twoSumClosest(nums2, target2);
console.log(`最接近目标 ${target2} 的数对的下标是:`, result2); 
// 输出: 最接近目标 1 的数对的下标是: [ [ 0, 1 ], [ 2, 5 ] ]
 
const nums3 = [1, 2, 3, 2, 1];
const target3 = 4;
const result3 = twoSumClosest(nums3, target3);
console.log(`最接近目标 ${target3} 的数对的下标是:`, result3);
// 输出: 最接近目标 4 的数对的下标是: [ [ 1, 2 ], [ 1, 3 ], [ 2, 4 ] ]
 
 
console.log(twoSumClosest([2, 7, 11, 15], 10));   // 输出: [0, 1] (2+7最接近10)
console.log(twoSumClosest([1, 3, 5, 8], 7));     // 输出: [1, 2] (3+5最接近7)
console.log(twoSumClosest([3, 8, 12, 17], 20));  // 输出: [1, 2] (8+12最接近20)
console.log(twoSumClosest([1, 1, 1, 1], 10));    // 输出: [0, 1] (1+1最接近10)
console.log(twoSumClosest([-1, 2, 1, -4], 1));   // 输出: [1, 2] (2+1最接近1)

12.时间戳输出对应文案:如 [一分钟内]刚刚、x分钟前、x小时前、昨天 xx:xx ,前天,【一星期内】星期几,【超过一星期】xx月xx日xx时xx分,【不在当年】xx年xx月xx日xx时xx分

function timeAgoIntl(timestamp){
    let inputTime
    if(typeof timestamp === 'number'){
        if (timestamp.toString().length === 10){
            inputTime = new Date(timestamp*1000)
        } else {
            inputTime = new Date(timestamp)
        }
    } else if(typeof timestamp === 'string'){
        inputTime = new Date(timestamp)
    } else if(timestamp instanceof Date){
        inputTime = timestamp
    } else {
        throw new Error('invalid timestamp')
    }
    const now = new Date()
    const diffInSeconds = (now - inputTime) / 1000
    const rtf = new Intl.RelativeTimeFormat('zh-CN',{numeric: 'auto'})
    const thresholds = [
        {limit:60, divisor:1, unit:'second'},
        {limit:3600, divisor:60, unit:'minute'},
        {limit:86400, divisor:3600, unit:'hour'},
        {limit:604800, divisor:86400, unit:'day'},// todo
    ]
    for(let i=0; i<thresholds.length; i++){
        if(diffInSeconds<thresholds[i].limit){
            const value = Math.floor(diffInSeconds/thresholds[i].divisor)
            return rtf.format(-value,thresholds[i].unit)
        }
    }
}
const timestampsIntl = [
    Date.now()-30*1000, // 刚刚
    Date.now()-5*60*1000, // 5分钟前
    Date.now()-5*3600*1000, // 5小时前
    Date.now()-5*86400*1000, // 5天前
]
timestampsIntl.forEach(ts => {
    console.log(timeAgoIntl(ts))
})
 

13.实现方法f,判断以下图结构中,是否存在闭环?并打印出闭环上的节点

image.png

function detectCycle(graph) {
  // 构建邻接表表示图
  const adjacencyList = {};
  for (const edge of graph) {
    const { src, dst } = edge;
    if (!adjacencyList[src]) adjacencyList[src] = [];
    adjacencyList[src].push(dst);
  }

  const visited = new Set(); // 已访问节点
  const stack = new Set(); // 当前路径上的节点(用于检测环)
  const cycleNodes = new Set(); // 存储闭环上的节点

  // 深度优先搜索函数
  function dfs(node) {
    if (stack.has(node)) {
      // 找到了环,将环上的节点加入到 cycleNodes
      cycleNodes.add(node);
      return node; // 返回环的起始节点
    }
    if (visited.has(node)) return null;

    visited.add(node);
    stack.add(node);

    if (adjacencyList[node]) {
      for (const neighbor of adjacencyList[node]) {
        const cycleStart = dfs(neighbor);
        if (cycleStart) {
          cycleNodes.add(node); // 当前节点属于环
          if (cycleStart === node) return null; // 环已经完整
          return cycleStart; // 继续向上返回环的起始节点
        }
      }
    }

    stack.delete(node); // 回溯时移除当前节点
    return null;
  }

  // 遍历所有节点,尝试检测环
  for (const node in adjacencyList) {
    if (!visited.has(node)) {
      dfs(node);
      if (cycleNodes.size > 0) {
        console.log("闭环上的节点:", Array.from(cycleNodes));
        return true;
      }
    }
  }

  console.log("图中不存在闭环");
  return false;
}

// 测试
var graph = [
  { src: 'g', dst: 'e' },
  { src: 'a', dst: 'b' },
  { src: 'f', dst: 'g' },
  { src: 'e', dst: 'f' },
  { src: 'c', dst: 'd' },
  { src: 'b', dst: 'c' },
];

detectCycle(graph); // ['g', 'f', 'e']

14.企鹅们都需要穿文化衫来拍照。一次采访中,记者随机遇到的企鹅,企鹅会告诉记者还有多少企鹅跟他穿一个颜色的文化衫(每个企鹅说的都是真实情况)。我们将这些回答放在 answers 数组里。返回鹅厂中企鹅的最少数量。

function minimumPenguins(answers) {
  const map = new Map();
  // 统计每个回答出现的次数
  for (let num of answers) {
    map.set(num, (map.get(num) || 0) + 1);
  }
  let minCount = 0;
  // 遍历 map 计算最少数量
  for (let [num, count] of map) {
    // 每组有 num + 1 只企鹅
    const groupSize = num + 1;
    // 至少需要 Math.ceil(count / groupSize) 个组
    const groups = Math.ceil(count / groupSize);
    // 累加企鹅的总数
    minCount += groups * groupSize;
  }
  return minCount;
}

// 示例测试
console.log(minimumPenguins([1, 1, 2])); // 输出: 5
console.log(minimumPenguins([1]));       // 输出: 2
function minimumPenguins(answers) {
  const countArray = []; // 用数组记录每个回答的次数
  // 统计每个回答出现的次数
  for (let num of answers) {
    countArray[num] = (countArray[num] || 0) + 1;
  }
  let minCount = 0;
  // 遍历 countArray 计算最少数量
  for (let num = 0; num < countArray.length; num++) {
    if (countArray[num] > 0) {
      const groupSize = num + 1; // 每组有 num + 1 只企鹅
      const groups = Math.ceil(countArray[num] / groupSize); // 至少需要的组数
      minCount += groups * groupSize; // 累加最少企鹅总数
    }
  }
  return minCount;
}

// 示例测试
console.log(minimumPenguins([1, 1, 2])); // 输出: 5
console.log(minimumPenguins([1]));       // 输出: 2

15.买股票的最佳时机含手续费 lc714

var maxProfit = function(prices, fee) {
    const n = prices.length;
    const dp = new Array(n).fill(0).map(v => new Array(2).fill(0));
    dp[0][0] = 0, dp[0][1] = -prices[0];
    for (let i = 1; i < n; ++i) {
        dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee);
        dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
    }
    return dp[n - 1][0];
};

16.对象扁平化

// 扁平化 Object  {a:1,b:{a:{c:1,d:2}}} => {a:1,c:1,d:2}
function flatObj(obj){
    // 补充完成
    const res = {}
    if(typeof obj !== 'object' || obj === null){
        return obj
    }
    for(const key in obj){
        const value = obj[key]
        if(typeof value === 'object' && !Array.isArray(value)){
            const child = flatObj(value)
            for(const leaf in child){
                res[leaf] = child[leaf]
            }
        }
        else {
            res[key] = obj[key]
        }
    }
    return res
}

const obj = {a:1,b:{a:{c:1,d:2}}}
console.log(flatObj(obj))

17.队列中可以看到的人 lc1944

var canSeePersonsCount = function(heights) {
  const n = heights.length;
  const stack = [];
  const res = new Array(n).fill(0);

  for (let i = n - 1; i >= 0; i--) {
      const h = heights[i];
      while (stack.length > 0 && stack[stack.length - 1] <= h) {
          stack.pop();
          res[i] += 1;
      }
      if (stack.length > 0) {
          res[i] += 1;
      }
      stack.push(h);
  }
  return res;
};
// 示例
const heights = [10, 6, 8, 5, 11, 9];
console.log(canSeePersonsCount1(heights));  // 输出: [3, 1, 2, 1, 1, 0]

18.找到嵌套属性值与对应路径

// 输入:
var a = {
    a: {
      b: {
        c: 1
      }, 
      d: [1,2]
    }, 
    e: 's'
  }
// 输出:[{key: 'abc', value: 1}, {key: 'ad', value: [1,2]}, {key: 'e', value: 's'}]

function findNestedProperties(obj) {
    const result = [];
    function recurse(currentObj, currentPath) {
      for (const key in currentObj) {
        if (currentObj.hasOwnProperty(key)) {
          const newPath = currentPath ? `${currentPath}${key}` : key;
  
          // 检查是否为基本数据类型或数组
          if (typeof currentObj[key] !== 'object' || currentObj[key] === null || Array.isArray(currentObj[key])) {
            result.push({ key: newPath, value: currentObj[key] });
          } else {
            // 如果是对象,则递归
            recurse(currentObj[key], newPath);
          }
        }
      }
    }
    recurse(obj, '');
    return result;
  }

19.实现深拷贝

function deepClone(obj, hash = new WeakMap()) {
  // 处理基本数据类型
  if (obj === null || typeof obj !== "object") return obj;

  // 避免循环引用
  if (hash.has(obj)) return hash.get(obj);

  // 处理特殊类型
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);

  // 创建新的对象或数组
  const copy = Array.isArray(obj) ? [] : {};
  hash.set(obj, copy);

  // 遍历对象属性
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepClone(obj[key], hash); // 递归拷贝
    }
  }

  return copy;
}

// 测试
const obj = {
  a: 1,
  b: [1, 2],
  c: { d: 3 },
  date: new Date(),
  reg: /test/gi,
};
obj.self = obj; // 循环引用

const cloned = deepClone(obj);
console.log(cloned);
console.log(cloned.date instanceof Date); // true
console.log(cloned.reg instanceof RegExp); // true

other

// app.js
 
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
 
const User = require('./models/User'); // 引入数据库
 
// 连接 MongoDB 数据库
mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.log('MongoDB connection error:', err));
 
// 设置视图引擎为 EJS
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
 
// 中间件设置
app.use(bodyParser.urlencoded({ extended: true }));  // 解析 URL 编码的请求体
app.use(bodyParser.json()); // 解析 JSON 请求体
 
// 静态文件托管
app.use(express.static(path.join(__dirname, 'public')));
 
// 首页路由
app.get('/', (req, res) => {
  res.render('index', { title: 'My Node Web App' });
});
 
// 简单的 POST 路由
app.post('/submit', (req, res) => {
  const { name, email } = req.body;
 
  const newUser = new User({ name, email });
  await newUser.save();
 
  res.send(`Data has been saved to the database: Name = ${name}, Email = ${email}`);
});
 
// 404 路由
app.use((req, res) => {
  res.status(404).send('Page not found');
});
 
// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});
 
 
// models/User.js 提交表单时将数据存储到数据库
 
const mongoose = require('mongoose');
 
const userSchema = new mongoose.Schema({
    name: String,
    email: String
});
 
const User = mongoose.model('User', userSchema);
module.exports = User;
 
 
 
// <!-- views/index.ejs -->
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= title %></title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
    <h1>Welcome to <%= title %></h1>
    <form action="/submit" method="POST">
        <label for="name">Name:</label>
        <input type="text" name="name" id="name" required><br><br>
        
        <label for="email">Email:</label>
        <input type="email" name="email" id="email" required><br><br>
 
        <button type="submit">Submit</button>
    </form>
</body>
</html>
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
 
# 创建一个 OpenAI 模型实例
llm = ChatOpenAI(model="gpt-4", temperature=0)
 
# 创建一个提示模板,用于代码优化
prompt = PromptTemplate(
    input_variables=["code"],
    template="你是一个前端开发专家,下面的 JavaScript 代码存在性能或可读性问题,请优化这段代码并给出优化后的版本。代码如下:\n{code}\n\n优化后的代码:"
)
 
# 使用 LLMChain 创建链
chain = LLMChain(llm=llm, prompt=prompt)
 
# 示例代码
code_to_optimize = """
function sumArray(arr) {
    let total = 0;
    for (let i = 0; i < arr.length; i++) {
        total += arr[i];
    }
    return total;
}
"""
 
# 调用 LangChain 链生成优化后的代码
optimized_code = chain.run({"code": code_to_optimize})
print(optimized_code)