字节一面 && 西门子一面

2,626 阅读4分钟

字节

全程给一个编辑器,写完之后面试官会问思路,难度中规中矩

写一个bachrequest 并发请求,最多同时请求max个,当第一个请求resolve,加入第二个请求,以此类推

思路: 递归

var urls = ['a','b','c','d','a','b','c','d']
var max = 2
var bach  = function () {
    if (max > 0 && urls.length) {
        let id = urls.shift()
        
        setTimeout(() => {
            // 执行请求
            console.log(id)
            // 请求执行后可以进行下一个
            bach(max++)
        },1000)
        bach(max--)
    }
}
bach()

react 组件实现 modal.show({durance:'1000',message:'hello'})

考察: createPortal ? 单例模式 ? 这题我不是太有把握

var  CreateModal = (function () {
    var instance = null
    function Modal() {
        class Modal {
            show({durance,message}) {
                let el = document.getElementsByTagName('body')[0];
                setTimeout(() => {
                    this.setState({visible:false})
                },1000)
                return visible ? ReactDOM.createPortal(
                    (<div>message</div>) : '' ,
                    el)
            }
        }
        if (!instance) {
            instance = new Modal()
       } 
        return  instance
    }
   return Modal 
}) ()
// 单例
var modal = new Modal()

modal.show({durance:'1000',message:'hello'})
modal.show({durance:'1000',message:'hello2'})

给一个dom 树 例如

 <div data="3">
   <div data="1">
     	<img data="2">
   		<p data="5"></p>
   </div>
</div>

要求返回 div div img 3 ;div div p 5

即返回路径和路径中的最大值

思路:回溯算法

var res = []
var backTrak = (dom,path,max) => {
        // 获取dom子元素,子元素为 0 则 为路径终点
        var children = dom.children
        if (!children.length) {
            res.push(path.join(' ') + max)
        }
        for(let i = 0 ; i < children.length ; i ++) {
            let child = children[i]
            var tagName = child.tagName
            var digital = child.digital
            backTrak(child,[...path,tagName],math.max(max,digital))
        }
}

西门子

主要是八股文

vue 和 react 的区别

我用的 vue 2 版本,开发过程感觉是对象编程,react 有函数式编程的感觉。总体来说其实 vue 比较顺手。

函数的节流与防抖。

都是防止函数的多次调用。 防抖是延迟执行(执行最后一次的调用),节流是每隔一段时间执行一次(执行第一次的调用)

http 优化相关, 例如图片怎么优化

DNS 预解析,可以预先获得ip

图片 CDN 加载,请求裁剪后的图片

小图使用base64 ,雪碧图 ,有WebP 选 WebP,因为 WebP 格式具有更好的图像数据压缩算法。

缓存 预加载 预渲染

公共组件库,less

因为之前有参与公共组件库的项目,所以被问了 开发公共组件需要注意什么,比如换肤功能要怎么做

需要注意的点我觉得除了通用性和 可扩展之外,方法命名很重要,需要让使用者看到方法名称就能猜出来你这个方法是有什么功能的。除此之外还要考虑到是提供一个方法给使用者,还是需要使用者传参数。过多的参数会使配置变得复杂,过多的方法也会让使用者望而却步。

至于换肤功能,之前的换肤是参照了ant , 一个颜色变量对应多个颜色,在换肤的时候改变颜色变量即可

css预编译的区别

这我真没了解过,查询后知道 Less是基于JavaScript,是在客户端处理的, Sass是基于Ruby的,是在服务器端处理的。

双token 刷新,access_token 和 refresh_token

不了解

性能优化

我答了 算法层面的性能优化, webpack 多核性能优化,使用 web-worker进行大运算内容,懒加载, loader 编译优化,当然还有很多我当场没记起来的。

怎么保证代码的规范?

eslint + pre-commit

当然,这种规范项目随着开发时间推移和开发人员水平的参差不齐,最后的代码不尽人意

所以需要加上代码 review

继承与原型链,原型链污染是什么,什么造成的

简单来说,对象有个_proto_ 指向 构造函数 的 原型,原型本身也是对象,原型_proto_ 指向 它的构造函数的原型,直到找到 Object.prototype 这个原生对象。

原型链污染 我真没听过 差了下 就是控制实例对象的proto属性,修改这个类所有对象的 proto ,此外还需 要使_proto_ 作为key被赋值,还需要一个条件为传递的参数需要是以json来做解析,否则_proto_会被当作原型而不是一个key,举例

let o1 = {}
let o2 = JSON.parse('{"a":1,"__proto__":{"b":2}}')
o3 = {}
o3.b

我并没有成功,难道漏洞修复了?

call apply bind 是什么

送分题,应该都会手写原理的吧

内存泄漏在哪里出现,怎么避免

没有销毁的定时器,闭包,递归无出口

避免我只能说注意写法

如果你接手一个项目,怎么做,怎么估计工时 ?举个例子

我举了之前重构代码的例子,首先让领导明白你重构过程可能会很艰难。把需要重构的页面分成 几个维度 1. 输入输出 使用 高频 2. 使用高频,输入输出低频 3. 使用低频

第一类需要 严格按照测试用例测试输入输出的数据,拉测试来检查之前用例的用意;第二类需要 按照用例和原代码对照; 第三类可以考虑不重构节省工时。

了解的设计模式

用的比较多的其实就是 单例 , 观察者, 代理模式

其他的多说了个 策略模式,装饰器模式

应该是有九大模式,其他的前端用的确实不多

设计模式对工程化的应用

我就想到webpack 的插件原理,tapable 是使用的观察者模式,提供给调用者一hook 进行开发