字节跳动,byteDance面经

2,622 阅读4分钟

css布局题

3个div,第一个高度100px,第三个高度100px,要求第二个高度自适应

  • 解法一: 通过计算属性高度使第二个高度自适应
<style>
.d {
    &:nth-of-type(1) {
        height: 100px;
        background: #ff0000;
    }
    &:nth-of-type(2) {
        height: calc(100vh - 200px);
        background: #00ff00;
    }
    &:nth-of-type(3) {
        height: 100px;
        background: #0000ff;
    }
}
</style>
<div class="d">A</div>
<div class="d">B</div>
<div class="d">C</div>
  • 解法二:通过flex布局
<style>
.flex{
    display:flex;
    flex-direction: column;
    flex-wrap: nowrap;
    width: 100%;
    height: 500px;
}
.d {
    &:nth-of-type(1) {
        height: 100px;
        background: #ff0000;
    }
    &:nth-of-type(2) {
        flex-grow: 1;
        background: #00ff00;
    }
    &:nth-of-type(3) {
        height: 100px;
        background: #0000ff;
    }
}
</style>
<div class="flex">
    <div class="d">A</div>
    <div class="d">B</div>
    <div class="d">C</div>
</div>

koa洋葱模型

function compose (middleware) {
    if (!Array.isArray(middleware)) {
        throw new Error('middleware must be array');
    }
    for (var i in middleware) {
        if (typeof middleware[i] !== 'function') {
            throw new Error('middlewares are not a function');
        }
    }
    return function (context, next) {
        let index = -1;
        return dispatch(0);
        function dispatch (i) {
            if (i <= index) {
                return Promise.reject();
            }
            index = i;
            fn = middleware[i];
            if (i === middleware.length) {
                fn = next;
            }
            if (!fn) {
                return Promise.resolve();
            }
            try {
                return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))
            } catch () {
                return Promise.reject();
            }
        }
    }
}

执行上下文,变量声明和函数声明

function Byte () {
    getName = function () {
        console.log(1);
    }
    return this;
}
Byte.getName = function () {
    console.log(2);
}
Byte.prototype.getName = function () {
    console.log(3);
}
var getName = function () {
    console.log(4);
}
function getName () {
    console.log(5);
}
Byte.getName();
getName();
Byte().getName();
getName();
new Byte.getName();
new Byte().getName();

2 4 1 1 2 3

简单说一下项目中webpack plugin的应用,实现

实际在应用sentry时,将每个入口文件需要打入的sentry.init({}),通过自定义plugin,entryOption钩子中应用

class SentryInit () {
    apply (compiler) {
        compiler.hooks.entryOption.tap('sentry-init', () => {
            ...
        })
    }
}
  • 参考vconsole-webpack-plugin

_.get()实现

let byteTest = {
    a: {
        b: {
            c: 1
        }
    },
    target: [
        'finder',
        {
            name: 'lee'
        }
    ]
}
_get(obj, 'a.b.c', 'target[0]', 'target[1].name')
// 打印 [1, 'finder', 'lee']
function _get() {
 // 请输入代码
}

lodash 的 深克隆实现,请留下你的答案

const cloneDeep = parent => {
    const parents = [];
    const children = [];
    const _clone = parent => {
        if (parent === null) {
            return null;
        }
        if (typeof parent !== 'object') {
            return parent;
        }
        let child;
        if (isType(parent) === '[object Array]') {
            child = [];
        } else if (isType(parent) === '[object Date]') {
            child = new Date(parent.getTime());
        } else if (isType(parent) === '[object RegExp]') {
            child = new RegExp(parent.source, getRegExp(parent));
            if (parent.lastIndex) {
                child.lastIndex = parent.lastIndex;
            }
        } else {
            let proto = Object.getPrototypeOf(parent);
            child = Object.create(proto);
        }
        let index = parents.indexOf(parent);
        if (index !== -1) {
            return children[index];
        }
        parents.push(parent);
        children.push(child);
        for (let i in parent) {
            child[i] = _clone(parent[i]);
        }
        return child;
    }
    return _clone(parent);
}

长列表优化

渲染一组超长的数据,列表渲染,如何优化

补充

这个是2020年的一些补充,

input输入限制number

要求输入后只返回数字类型,其余都过滤,当时表达的也有点含糊,

  • 我的第一反应是下面这样子,为了给点面子,我在想我写个方法吧
<input type="number">
  • 于是我的第二反应,来个正则吧
// 把所有非数字剔除 版本1
e.target.value = e.target.value.replace(/[^\d]/g, '')
  • 大佬说你正则能搞定?我慌了,for循环总行了吧
let stringList = [...e.target.value]
let result = '';
for (let i = 0; i < stringList.length; i++) {
    if (typeof parseInt(stringList[i]) === 'number') {
        result += stringList[i];
    } else if (stringList[i] === '.') {
        // 其实这里应该加个判断,只保留最前面第一次获取的小数点,后面的都不要了
        result += stringList[i];
    }
}
return result;
  • 大佬恐惧症,大佬说,for循环性能不行啊,于是还是回归正则,但是正则写错了多了个|,有点bug
// 想了想不对浮点数怎么处理? 版本2 错误版本 会把|也保留
e.target.value = e.target.value.replace(/[^\d|.]/, '')
  • 大佬说这个很简单,于是开始一顿操作,给我写他的思路
var val = e.target.value;
if (isNumber(val)) {
    return;
}
if (/./$.test(val) {} 
...
...
...

我有点急了,我说你这样xxx,xxx,xxx,中文情况咋办,输入了多个小数点咋办,于是大佬不写了

  • 大佬说说了半天了就这样吧,结束了

  • 后知后觉的我,我回头想想还是正则,很多情况下还是临场发挥不是很好

<input type="text" onchange="toNumber(event)">
    
    function toNumber (event) {
        input = event.target.value
        input = input.replace(/[^\d.]/g, '')
        console.log(input)
        idx = input.indexOf('.')
        lastIdx = input.lastIndexOf('.')
        console.log(idx, lastIdx)
        outPut = input.replace(/[.]/g, '')
        if (idx != -1 && idx === lastIdx && lastIdx !== input.length - 1) {
            return event.target.value = outPut.slice(0, idx) + '.' + outPut.slice(idx)
        }
        return event.target.value = outPut
    }

mpvue的runtime-compile是怎么实现

0.1 + 0.2 = 0.3 怎么处理

这个问题怪我,之前看过,但是忘了,后来想想有一个解决,就是在加之前全部乘1000,再除1000

node操作error日志

error,warn,...这些日志类型,从日志中筛选出所有error的类型日志信息出来,这个node相关的,我不会

少侠留步,感谢star一下