[关闭]
@GaoyuanHfut 2020-05-14T12:30:22.000000Z 字数 6110 阅读 417

字节跳动

  1. 实现一个bind函数

    Function.prototype.bind = function () {
    var self = this, // 保存原函数
    context = [].shift.call(arguments), // 保存需要绑定的this上下文
    args = [].slice.call(arguments); // 剩余的参数转为数组
    return function F() {
    if (this instanceof F) {
    return new self(...args, ...arguments)
    }
    // 返回一个新函数
    self.apply(context,[].concat.call(args, [].slice.call(arguments)));
    }
    }

  2. 千位加,
    toLocaleString方法即可

  3. 原型继承和 Class 继承
    组合继承
    通过Parent.call(this) 继承父类的属性,然后改变子类的原型为 new Parent() 来继承父类的函数。

这种继承方式优点在于构造函数可以传参,不会与父类引用属性共享,可以复用父类的函数,但是也存在一个缺点就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。

寄生组合继承
Child.prototype = Object.create(Parent.prototype, {
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true
}
})
父类的原型赋值给了子类,并且将构造函数设置为子类

class 实现继承的核心在于使用 extends 表明继承自哪个父类,并且在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)。
4. 事件循环
有微则微,无微则宏
macro-task: setTimeout, setInterval, setImmediate, I/O, UI rendering.
micro-task: process.nextTick, Promise(原生),Object.observe,MutationObserver
process.nextTick 高于 Promise
5. 柯里化
柯里化的目的是,减少代码冗余,以及增加代码的可读性,bind典型
6. https 获取加密密钥,http 的方法有哪几种
非对称加密,公钥和私钥,

1、OPTIONS 测试服务器的功能性
2、HEAD 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回
3、GET 向特定的资源发出请求。
4、POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
5、PUT 向指定资源位置上传其最新内容
6、DELETE 请求服务器删除Request-URL所标识的资源
7、TRACE 回显服务器收到的请求,主要用于测试或诊断
8、CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

  1. event 类 on once 方法
    class Event {
    constructor() {
    this.handlers = { // 记录所有的事件和处理函数

    }
    

    }
    /* *

    • on 添加事件监听
    • @param type 事件类型
    • @param handler 事件回调
    • on('click', ()=>{})
    • */
      on(type, handler, once=false) {
      if (!this.handlers[type]) {
      this.handlers[type] = [];
      }
      if (!this.handlers[type].includes(handler)) {
      this.handlers[type].push(handler);
      handler.once = once;
      }
      }
      // 触发
      trigger(type, eventData = {}, point=this) {
      if (this.handlers[type]) {
      this.handlers[type].forEach(f => {
      f.call(point, eventData);
      if (f.once) {
      this.off(type, f)
      }
      });
      }
      }
      }
  2. ==的隐式转化
    统一转Number,对象转成了【object,object】
  3. 闭包
    函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包
  4. 二叉树中序遍历
    var res=[];
    //栈
    var s=[];
    var p = root;

    while (p || s.length>0) {
        //直至左节点为空,即没有左节点为止
        while (p) {
            s.push(p);
            p = p.left;
        }
        //出栈,存放根节点
        p = s.pop();
        res.push(p.val);
        p = p.right;
    }
    return res;
    
  5. sum(1)(2)(3).valueOf() 返回 6
    function sum(a){
    return function(b){
    return function(c){return a+b+c};
    }
    }
  6. 多空格字符串格式化为数组 split(' ')
  7. Jsonp 跨域
    JSONP 的原理很简单,就是利用 标签没有跨域限制的漏洞。通过 标签指向一个需要访问的地址并提供一个回调函数来接收数据当需要通讯时。
  8. 前端做并发请求控制
    promise.all
  9. 节流函数
    防抖
    `function debounce(func, wait) {
    var timeout;

    return function () {
    // 确保func里面的this还是对的
    var context = this;
    // 实参继续用
    var args = arguments;
    clearTimeout(timeout)
    timeout = setTimeout(function(){
    func.apply(context, args)
    }, wait);
    }
    }`

节流

throttle(fn,wait) {
let canRun = true; // 通过闭包保存一个标记
return function () {
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
canRun = false; // 立即设置为false
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
fn.apply(this, arguments);
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
canRun = true;
}, wait);
};
}

16. 指定日期格式化
new Date().getTime() + 3000 //加3秒
17. 中间件机制
app.use([path],function)
18. html meta 标签有啥作用

19. cookie 结构有什么字段
value 如果用于保存用户登录态,应该将该值加密,不能使用明文的用户标识
http-only 不能通过 JS 访问 Cookie,减少 XSS 攻击
secure 只能在协议为 HTTPS 的请求中携带
same-site 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击
20. bfc 块级格式化上下文
BFC规定了内部的Block Box如何布局。
定位方案:
内部的Box会在垂直方向上一个接一个放置。
Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠。
每个元素的margin box 的左边,与包含块border box的左边相接触。
BFC的区域不会与float box重叠。
BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
计算BFC的高度时,浮动元素也会参与计算。
满足下列条件之一就可触发BFC

根元素,即html
float的值不为none(默认)
overflow的值不为visible(默认)
display的值为inline-block、table-cell、table-caption
position的值为absolute或fixed

  1. css 为什么要放在头部
    在加载html生成DOM tree的时候,就可以同时对DOM tree进行渲染。
    这样可以防止闪跳,白屏或者布局混乱。

  2. deepClone
    JSON.parse(JSON.stringify(object))

function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}

if (!isObject(obj)) {
throw new Error('非对象')
}

let isArray = Array.isArray(obj)
let newObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach(key => {
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})

return newObj
}

  1. 回流重绘
    • 重绘
      由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, color、background-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。
    • 回流
      回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。
  2. 换行字符串格式化
  3. 原码,补码,反码
  4. 事件委托
    事件注册在父节点上,节省内存
    不需要给子节点注销事件
  5. 数组去重
    Array.from(new Set(arr))
  6. 列表 diff 中 key 的作用
    diff时无需改动
  7. Vue v-model 原理
  8. mvvm的原理
    vue是采用数据劫持配合发布者-订阅者模式,通过object.defineProperty来劫持各个属性的set和get,在数据变动时,发布信息给依赖收集器,去通知观察者,做出对应的回调函数,区更新视图。
    Mvvm作为绑定的入口,整合observer,compile和watcher三者,通过observer来监听model的数据变化,通过compile来解析编译模板指令,最终利用watcher搭起observer和compile的桥梁,做到双向绑定。

vue的生命周期

父组件: beforeCreate -> created -> beforeMount
子组件: -> beforeCreate -> created -> beforeMount -> mounted
父组件: -> mounted
总结:从外到内,再从内到外
30. 场景题:Vue CheckBoxGroup/CheckBox 设计

  1. 可以批量请求数据,所有的URL地址在urls参数中,同时可以通过max参数 控制请求的并发度。当所有的请求结束后,需要执行callback回调。发请求的函数可以直接使用fetch
    http://www.mamicode.com/info-detail-2636279.html
  2. 实现一个方法,参数是一个 generator 函数,执行结果是执行完所有 generator 中的 yield
  3. 获取页面所有 img 并且下载
  4. 两个同源 tab 之间的交互,数据同步 localStorage
  5. 实现一个 Promise.all
    https://blog.csdn.net/Yvan_Lin/article/details/81100303
  6. webpack 打包原理 的优化
  7. 定位体积大的模块(webpack插件webpack-bundle-analyzer来查看整个项目的体积结构)
  8. 提取公共模块(webpack自带的插件CommonsChunkPlugin)
  9. 通过CDN引用
  10. 移除不必要的文件(IgnorePluginContextReplacementPlugin)
  11. 开启Gzip压缩
    开启gzip压缩可以减少HTTP传输的数据量和时间,从而减少客户端请求的响应时间,由于降低了请求时间,页面的加载速度也会得到提升,会有更快的渲染速度,极大地改善了用户体验。由于现在基本上所有的主流浏览器都支持Gzip的压缩方式,只需要对服务器进行相关设置即可,这里就不具体讲如何配置服务器。
  12. 压缩混淆代码
    我们平常也会对代码进行压缩混淆,可以通过UglifyJS等工具来对js代码进行压缩,同时可以去掉不必要的空格、注释、console信息等,也可以有效的减小代码体积。
  13. babel 原理

自研组件和外面element和iview的不同

这是基于我简历项目描述提的问题
1. 样式上符合公司统一风格
2. 插件优化,由cooking修改成了基于webpack4的vue-cli3,Vue CLI 3 内部集成了插件系统,过插件系统可以为 hui-vue 2.0 安装辅助开发插件,从而提升开发的效率和提高开发的质量
3. 样式从post-css修改成了scss
在 HUI 1.x 版本中,我们遵循 Element 1.x 的形式使用 postcss,主要使用 postcss-salad 作为 CSS 的解决方案。但是 postcss-salad 已经有超过两年未维护,因此 HUI 2.0 版本决定替代掉 postcss-salad。颜色由主题色通过变量的方式衍生出去,实现整体色系的变化
4. 按需引入不采用构建的形式,而是引入源码的形式,不需要对单组件样式进行额外的构建,因此这里去除Gulp构建工具。
5. 引入 VuePress,在 hui-vue 1.x 中,演示 Demo 采用了markdown-it结合vue-markdown-loader对 Demo 中 md 文件格式的 vue 语法进行解析,并使用cooking watch热启动从而实现 hui-vue 1.x 控件的开发态调试,而构建部署演示 Demo 的静态网站则需要使用cooking build命令构建,这就需要对演示 Demo 网站的构建额外产生一套 Webpack配置,并且配置还需要区分开发态和生产态,这使得配置变得非常复杂并且难以维护
6. Cz 配置
Git 每次提交代码,都要写 commit message,规范的 commit message 可以对项目管理维护起到积极的作用
7. 升级日志生成
提供规范的代码提交记录可以使用 conventional-changelog 来自动生成 changelog
8. husky 钩子设计
良好的代码规范有助于项目的维护,为了防止一些不规范的代码 commit并push到远端,我们可以在git命令执行前用一些钩子来检测并阻止。

你好,我叫高源。2017年6月毕业于合肥工业大学信息与计算科学专业,在校期间,参与到合工大物联网实验室接触到了前端开发并参于了导师的几个项目学习提升自己。2017年2月参与海康威视实习并于当年7月毕业后就职于海康威视交通事业部。在职期间,参与多个业务项目开发和技术预研,2018获得年度绩效良好,并在2019年跨级评审通过。新的一年,想去接触新事物新挑战,重新出发。以上是我的自我介绍,谢谢。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注