字节前端一面面经

42 阅读5分钟

1.自我介绍

2.说项目亮点

3.AI相关的了解吗

4.agent怎么跑起来的,设计agent关注的点,agent接入插件,插件干嘛的,怎么接,模型怎么调用插件的

5.skill和MCP的区别

6.封装成skill和在窗口将skill内容直接输入,有什么区别

7.前端框架相对原生JS的差异

8.js事件循环,具体问题输出

9.实现深拷贝,要考虑多种类型,包括(Date, RegExp),还要考虑自循环(obj.self = obj)

以下是针对**完善版深拷贝函数**的多种测试用例,覆盖各种边界情况和数据类型:

## 完善版深拷贝函数(用于测试)

```javascript
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 cloneObj = Array.isArray(obj) ? [] : {};
    hash.set(obj, cloneObj);
    
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloneObj[key] = deepClone(obj[key], hash);
        }
    }
    
    return cloneObj;
}

测试用例集合

1. 基础数据类型测试

console.log('=== 基础数据类型测试 ===');

// 基本类型
const test1 = {
    number: 123,
    string: 'hello',
    boolean: true,
    nullValue: null,
    undefined: undefined,
    symbol: Symbol('test')
};

const cloned1 = deepClone(test1);
console.log('原始:', test1);
console.log('克隆:', cloned1);
console.log('是否相等:', test1 === cloned1); // false
console.log('symbol 复制:', cloned1.symbol === test1.symbol); // true (Symbol 是基本类型)

2. 嵌套对象和数组测试

console.log('\n=== 嵌套对象和数组测试 ===');

const test2 = {
    name: 'parent',
    address: {
        city: 'Beijing',
        zip: '100000',
        location: {
            lat: 39.9042,
            lng: 116.4074
        }
    },
    hobbies: ['reading', 'coding', { outdoor: 'running' }],
    scores: [
        { math: 90, english: 85 },
        { math: 95, english: 88 }
    ]
};

const cloned2 = deepClone(test2);
cloned2.address.city = 'Shanghai';
cloned2.hobbies[2].outdoor = 'swimming';
cloned2.scores[0].math = 100;

console.log('原始 address.city:', test2.address.city);    // Beijing
console.log('克隆 address.city:', cloned2.address.city);  // Shanghai
console.log('原始 hobbies[2].outdoor:', test2.hobbies[2].outdoor); // running
console.log('克隆 hobbies[2].outdoor:', cloned2.hobbies[2].outdoor); // swimming
console.log('原始 scores[0].math:', test2.scores[0].math); // 90
console.log('克隆 scores[0].math:', cloned2.scores[0].math); // 100

3. 循环引用测试

console.log('\n=== 循环引用测试 ===');

const test3 = {
    name: 'circular',
    child: {}
};
test3.self = test3;  // 自引用
test3.child.parent = test3;  // 循环引用

const cloned3 = deepClone(test3);
console.log('原始 self === original:', test3.self === test3); // true
console.log('克隆 self === cloned:', cloned3.self === cloned3); // true
console.log('克隆 child.parent === cloned:', cloned3.child.parent === cloned3); // true
console.log('循环引用处理成功!');

4. Date 和 RegExp 测试

console.log('\n=== Date 和 RegExp 测试 ===');

const test4 = {
    currentDate: new Date('2024-01-15T10:30:00'),
    pastDate: new Date(2020, 5, 20),
    pattern: /test\w+/gi,
    complexPattern: /^[a-z]{3,5}\d{2}$/,
    regexWithFlags: new RegExp('ab+c', 'gi')
};

const cloned4 = deepClone(test4);
cloned4.currentDate.setFullYear(2025);
cloned4.pattern.lastIndex = 5;

console.log('原始 currentDate:', test4.currentDate.toISOString()); // 2024-01-15T10:30:00.000Z
console.log('克隆 currentDate:', cloned4.currentDate.toISOString()); // 2025-01-15T10:30:00.000Z
console.log('原始 pattern test:', test4.pattern.test('test123')); // true
console.log('克隆 pattern test:', cloned4.pattern.test('test123')); // true
console.log('Date 和 RegExp 独立复制成功!');

5. 函数和特殊对象测试

console.log('\n=== 函数和特殊对象测试 ===');

const test5 = {
    // 普通函数
    sayHello: function() {
        return `Hello, ${this.name}`;
    },
    // 箭头函数
    add: (a, b) => a + b,
    // 带属性的函数
    method: function() {
        return 'method called';
    },
    // 函数对象
    callback: function(cb) {
        return cb();
    }
};
test5.method.prop = 'function property';

const cloned5 = deepClone(test5);
console.log('函数是否相同:', test5.sayHello === cloned5.sayHello); // true (函数是引用类型)
console.log('函数属性是否复制:', cloned5.method.prop); // 'function property'
console.log('调用克隆函数:', cloned5.sayHello.call({ name: 'World' })); // 'Hello, World'

6. 混合复杂对象测试

console.log('\n=== 混合复杂对象测试 ===');

const test6 = {
    id: 1,
    metadata: {
        created: new Date(),
        tags: ['important', 'test'],
        stats: {
            views: 1000,
            likes: 500
        }
    },
    data: [
        { type: 'A', value: 10, active: true },
        { type: 'B', value: 20, active: false }
    ],
    pattern: /test/gi,
    getSummary() {
        return `${this.id}: ${this.metadata.stats.views} views`;
    }
};

const cloned6 = deepClone(test6);
cloned6.metadata.stats.views = 2000;
cloned6.data[0].value = 999;
cloned6.metadata.tags.push('new');

console.log('原始 views:', test6.metadata.stats.views); // 1000
console.log('克隆 views:', cloned6.metadata.stats.views); // 2000
console.log('原始 data[0].value:', test6.data[0].value); // 10
console.log('克隆 data[0].value:', cloned6.data[0].value); // 999
console.log('原始 tags:', test6.metadata.tags); // ['important', 'test']
console.log('克隆 tags:', cloned6.metadata.tags); // ['important', 'test', 'new']

7. 边界情况测试

console.log('\n=== 边界情况测试 ===');

// 空值测试
const test7_1 = null;
const test7_2 = undefined;
const test7_3 = '';
const test7_4 = 0;
const test7_5 = false;

console.log('null 克隆:', deepClone(test7_1)); // null
console.log('undefined 克隆:', deepClone(test7_2)); // undefined
console.log('空字符串克隆:', deepClone(test7_3)); // ''
console.log('数字 0 克隆:', deepClone(test7_4)); // 0
console.log('false 克隆:', deepClone(test7_5)); // false

// 空对象和数组
const test7_6 = {};
const test7_7 = [];
console.log('空对象克隆:', deepClone(test7_6)); // {}
console.log('空数组克隆:', deepClone(test7_7)); // []

// 深层嵌套
const deepNested = { level1: { level2: { level3: { level4: { value: 'deep' } } } } };
const clonedDeep = deepClone(deepNested);
clonedDeep.level1.level2.level3.level4.value = 'modified';
console.log('原始深度值:', deepNested.level1.level2.level3.level4.value); // 'deep'
console.log('克隆深度值:', clonedDeep.level1.level2.level3.level4.value); // 'modified'

8. 性能和大数据测试

console.log('\n=== 性能测试 ===');

// 生成大数据对象
const largeData = {
    users: Array.from({ length: 1000 }, (_, i) => ({
        id: i,
        name: `User${i}`,
        email: `user${i}@example.com`,
        profile: {
            age: 20 + (i % 50),
            city: `City${i % 100}`,
            tags: Array.from({ length: 10 }, (_, j) => `tag${j}`)
        }
    })),
    metadata: {
        total: 1000,
        timestamp: new Date(),
        settings: {
            theme: 'dark',
            language: 'zh-CN'
        }
    }
};

console.time('深拷贝大数据');
const clonedLarge = deepClone(largeData);
console.timeEnd('深拷贝大数据');

// 验证修改不影响原对象
clonedLarge.users[0].profile.age = 999;
console.log('原始 age:', largeData.users[0].profile.age); // 20
console.log('克隆 age:', clonedLarge.users[0].profile.age); // 999

9. 完整性验证测试

console.log('\n=== 完整性验证测试 ===');

function testDeepCloneCompleteness() {
    const original = {
        a: 1,
        b: 'string',
        c: true,
        d: null,
        e: undefined,
        f: [1, 2, { g: 3 }],
        h: { i: 4, j: { k: 5 } },
        l: new Date(),
        m: /test/gi
    };
    
    const cloned = deepClone(original);
    
    // 测试结果汇总
    const results = {
        '基本类型复制': original.a === cloned.a,
        '字符串复制': original.b === cloned.b,
        '布尔复制': original.c === cloned.c,
        'null 复制': original.d === cloned.d,
        'undefined 复制': original.e === cloned.e,
        '数组独立': original.f !== cloned.f && original.f[0] === cloned.f[0],
        '对象独立': original.h !== cloned.h && original.h.i === cloned.h.i,
        'Date 独立': original.l !== cloned.l && original.l.getTime() === cloned.l.getTime(),
        'RegExp 独立': original.m !== cloned.m && original.m.source === cloned.m.source
    };
    
    console.table(results);
    
    const allPassed = Object.values(results).every(v => v === true);
    console.log('所有测试通过:', allPassed ? '✅ 是' : '❌ 否');
}

testDeepCloneCompleteness();

10. 错误处理和防御性测试

console.log('\n=== 错误处理和防御性测试 ===');

// 测试不可扩展对象
const frozen = Object.freeze({ a: 1, b: { c: 2 } });
try {
    const clonedFrozen = deepClone(frozen);
    console.log('冻结对象克隆成功:', clonedFrozen);
} catch (e) {
    console.log('冻结对象克隆失败:', e.message);
}

// 测试带有 getter/setter 的对象
const objWithGetter = {
    _value: 10,
    get value() { return this._value; },
    set value(v) { this._value = v; }
};

const clonedGetter = deepClone(objWithGetter);
console.log('getter/setter 克隆:', clonedGetter.value); // 10
clonedGetter.value = 20;
console.log('修改克隆后的值:', clonedGetter.value); // 20
console.log('原始值未变:', objWithGetter.value); // 10

运行所有测试

// 一次性运行所有测试
function runAllTests() {
    const tests = [
        { name: '基础数据类型', fn: test1 },
        { name: '嵌套对象', fn: test2 },
        { name: '循环引用', fn: test3 },
        { name: 'Date/RegExp', fn: test4 },
        { name: '函数处理', fn: test5 },
        { name: '混合对象', fn: test6 },
        { name: '边界情况', fn: test7 },
        { name: '大数据性能', fn: test8 },
        { name: '完整性验证', fn: test9 },
        { name: '错误处理', fn: test10 }
    ];
    
    tests.forEach(test => {
        console.log(`\n📋 运行测试: ${test.name}`);
        try {
            if (typeof test.fn === 'function') {
                test.fn();
            }
        } catch (error) {
            console.error(`❌ 测试失败: ${error.message}`);
        }
    });
}

// 注意:需要将上面的测试代码包装成函数形式
// 实际使用时将 test1, test2 等改为对应的函数名

这些测试用例覆盖了深拷贝函数可能遇到的各种场景,可以用来验证实现的正确性和健壮性。