mj

字节跳动

一面

1. 合并对象

// 测试用例
// 输入
const a={foo:{bar:0},arr:[1,3,{a:{b:1}}]}
const b={foo:{bar:1},arr:[1,2,{b:{a:1}}]}
// 输出,新对象不影响源对象
{foo:{bar:1},arr:[1,2,{a:{b:1},b:{a:1}}]}
function merge(a,b){}

合并对象实现

function getType(o) {
return Object.prototype.toString.call(o);
}
function deepClone(obj, weakMap = new WeakMap()) {
if (!(obj instanceof Object)) return obj;
var isArray = obj instanceof Array;
var res = isArray ? [] : {};
if (!isArray) {
if (weakMap.get(obj)) return {};
weakMap.set(obj, {}.toString.call(obj));
}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
res[key] = deepClone(obj[key], weakMap);
}
}
return res;
}
function merge(a, b) {
if (getType(a) !== getType(b)) {
return deepClone(b);
}
if (!(a instanceof Object)) {
return b;
}
const isArray = a instanceof Array;
const res = isArray ? [] : {};
for (let key in b) {
if (b.hasOwnProperty(key)) {
res[key] = merge(a[key], b[key]);
}
}
for (let key in a) {
if (res[key] === undefined && a.hasOwnProperty(key)) {
res[key] = deepClone(a[key]);
}
}
return res;
}

2. 手写深拷贝加循环引用处理

3. 手写bind

4. 盒子模型

5. 微任务、宏任务

6. 异步执行顺序题

明源云

笔试题

跨域解决方案

http缓存

code金额千分位格式化

code数组扁平化

code深拷贝

code sumRange函数

  • 题目

const nums = [-2, 0, 3, 5, -1, 4]
// nums不可修改只能读
// 实现一个函数sumRange,计算数组索引i,j之间的元素和,包含i,j
// sumRange会频繁调用,注意时间复杂度
// nums长度大于1w
function sumRange(i, j) {}
// test
sumRange(0, 2) // 1
sumRange(1, 3) // 8
sumRange(3, 5) // 9
  • 实现

function cacheSumRange(nums) {
const cache = []
nums.reduce((acc, cur, index) => (cache[index] = acc + cur), 0)
return function (i, j) {
return cache[j] - (cache[i - 1] || 0)
}
}
const sumRange = cacheSumRange(nums)

code实现LazyMan

  • 题目

// 实现LazyMan
LazyMan('jack').sleep(3000).eat('篮球').eat('rap').eat('唱、跳')
// hi,I'm zhaojian
// 阻塞3s
// 篮球
// rap
// 唱、跳
LazyMan('bitch').eat('高').sleep(5000).eat('富').eat('帅')
// hi,I'm xjq
// 高
// 阻塞5s
// 富
// 帅
LazyMan('lurenjia').sleepFirst(3000).eat('吹').eat('牛')
// 阻塞3s
// hi,I'm lurenjia
// 吹
// 牛
  • 实现

const stepObj = {
eat: async function ({ str }) {
console.log(str)
},
sleep: async function ({ delay }) {
return sleep(delay)
},
sleepFirst: async function ({ delay }) {
return sleep(delay)
},
talk: async function ({ name }) {
console.log(`I'm ${name}`)
},
}
async function sleep(delay) {
return new Promise((r, j) => setTimeout(r, delay))
}
function LazyManConstructor(name) {
this.step = []
this.name = name
this.step.push({ name: 'talk', params: { name } })
async function fn() {
while (this.step.length) {
const { name, params } = this.step.shift()
if (this.step.length) {
if (this.step[0].name === 'sleepFirst') {
const { name: lateName, params: lateParams } = this.step.shift()
await stepObj[lateName](lateParams)
}
}
await stepObj[name](params)
}
}
setTimeout(fn.bind(this), 0)
return this
}
LazyManConstructor.prototype.eat = function (str) {
this.step.push({ name: 'eat', params: { str } })
return this
}
LazyManConstructor.prototype.sleep = function (delay) {
this.step.push({ name: 'sleep', params: { delay } })
return this
}
LazyManConstructor.prototype.sleepFirst = function (delay) {
this.step.push({ name: 'sleepFirst', params: { delay } })
return this
}
function LazyMan(name) {
return new LazyManConstructor(name)
}