实习
    17期-MHJ
    工作地点:
    工作性质:
    部门:待定
    一面:2020.10

    一面
    跨域,解决方案
    CORS
    为什么JSONP可以实现跨域

    XSS攻击和CSRF攻击
    为什么要去匹配&符号
    如果攻击者输入了script标签的话,怎么做

    原型,prototype,constructor,proto

    构造函数

    箭头函数
    没有自己的arguments那怎么拿到arguments

    盒模型

    H5新增

    flex有哪些属性

    css选择器优先级

    get和post区别
    尤其在数据包发送的区别

    let,const,var

    防抖和节流

    数组常见API

    cookie,sessionStorage,localStorage

    缓存(强缓存和协商缓存)
    协商缓存的响应首部字段是什么

    时间复杂度

    17期
    工作地点:
    工作性质:
    部门:待定

    遇到不会的,先跟面试官说思考一下,再委婉的说没了解到

    一面
    css画一个三角形
    border(具体自己实现一下哈)
    css画等边三角形
    同样用border,画个菱形,截一半
    cookie和localStorage的区别
    cookie,sessionStorage,localStorage的区别:都是保存在浏览器端,都是同源的sessionStorage随当前窗口而关闭,localStorage和cookie 在所有同源窗口中都是共享的;cookie,cookie用来存储sessionid作为唯一标识用户最合适cookie数据不能超过4k,因为每次http请求都会携带
    cookie和session的区别 cookie存放在浏览器,session存放在session;session比较安全;考虑安全应该应该用session,考虑服务器性能应该用cookie
    CSRF攻击是啥,如何防范
    CSRF/XSRF:跨站请求伪造;伪装成受信任用户的请求来利用受信任的网站;防御:检查Referer字段,该字段标明请求来源于哪个地址,我们可以拒绝一切非本站发出的请求,避免CSRF的跨站特性;通过token或者验证码来检测用户提交
    上面的防御是否安全,如果黑客连上面的防御也能伪造呢(这个问题我同样也答不上)
    cookie可以设置哪些字段
    name,value
    domain,访问此cookie的域名(baidu.com为顶级域名,www.baidu.com为二级域名)
    path,可以访问此cookie的页面路径
    expires / max-Age
    size 此cookie的大小
    http字段 httpOnly
    secure 是否只能通过https来传递次
    说一下协商缓存
    协商缓存相关字段有Last-Modified (精度是秒的级别,也就是说1秒内更改资源的话,该字段不起作用,所以有了etag)/ If-Modified-Since(缓存过期并且资源已修改才会返回,200;最常见的应用场景是来更新没有特定 ETag 标签的缓存实体),Etag / If-None-Match(上一次设置Etag的值)
    https为什么安全,怎么做到安全,又有什么缺点
    https: 在http下加入了ssl层,建立信息安全通道,采用非对称加密;加密传输协议;端口443
    https原理
    web服务器需要先建立ssl连接
    服务器收到客户端的https url请求后,将包含公钥的证书返回给客户端
    建立会话秘钥,通过网站的公钥来加密会话秘钥
    web服务器通过私钥来解开会话秘钥,通过会话秘钥加密与客户端之间的通信
    https协议缺点
    握手阶段时间比http长
    缓存没有http高效,增加数据开销
    ssl证书需要成本,且不能在同一个ip上绑定多个域名
    http2.0特性内容安全,基于https的 二进制格式,传输信息分割为更小的消息和帧,采用二进制编码,让协议有更多的扩展性,比如用帧来传输数据和指令 多路复用增强了长连接,request请求可以随机的混杂在一起;支持流的优先级,告诉服务端优先传输哪些资源
    传输速度会不会比1.0快
    会,而且快了很多
    减少了网络延迟
    通过二进制分帧实现低延迟和高吞吐量
    前端优化
    降低请求数 合并资源,减少http请求,minify和gzip压缩,webp,lazyload
    提高请求速度 预解析dns,减少域名数,并行加载,cdn分发
    渲染 JS/CSS优化,加载顺序,服务端渲染
    缓存 http缓存请求,离线缓存manifast,离线数据缓存localStorage
    vue的响应式原理,对数组和对象怎么实现
    非数组
    请说一下响应式数据的理解
    对象内部通过defineReactive方法,使用Object.defineProperty将属性进行劫持,并且只会劫持已经存在的属性,对于数组则是通过重写数组方法来实现数组的响应式
    并且只能是数组常用的方法(push,pop,shift,unshift,sort,splice,reverse),对于直接通过下标或者数组长度修改数组并不会产生响应式,或者用$set(数组,下标,更新后的值),$set(对象,属性名,更新后的值)来增加对象属性,直接添加的话不会被defineProperty劫持到(因为初始化data的时候就对数据进行响应式劫持,后续增加的属性不会被劫持到)
    对象有多层次时使用递归对每一层进行响应式劫持,而vue3中响应式实现使用的是proxy
    每个属性都有自己的dep属性,用来存放它所依赖的watcher,当属性变化时,会通知到依赖的每个watcher去执行
    性能方面
    对象层级越深,性能会越差
    不需要响应的数据可以不用放到data中
    可以用Object.freeze()来冻结对象
    const data = { count: 1 }; // 获取属性时,暂时存放当前依赖 let acitve = null; // 每个属性都有自己的依赖集dep,当属性变化时,执行自己的dep中所有的依赖 const dep = []; // data属性的数据劫持,只会劫持已经存在的属性 function defineProperty (obj) { for (const prop in obj) { let value = obj[prop]; Object.defineProperty(obj, prop, { get() { // 获取属性时,判断当前属性有无依赖,有的话就添加到依赖集dep中 if (active) { dep.push(acitve); } return value; }, set(newValue) { value = newValue; // 当属性变化时,执行当前属性的所有依赖 dep.forEach(watcher => watcher()); } }); } } defineProperty(data); // 监听属性变化的依赖 const wathcer = (fn) => { // 将依赖函数保存到active中,为了获取数据时能存到dep中 active = fn; fn(); // active设为null,可能有的属性不需要依赖 active = null; }; // count属性变化时,重新设置app.innerHtml的值 watcher(() => { // 这个就是count的依赖,当后续更改count时就需要为app.innerHtml重新赋值 app.innerHTML = data.count; });

    响应数组
    数组响应式
    重写数组7个会改变原数组的方法,只有用这7种方法才会触发数组对应的watcher进行更新
    $set()核心内部用的是splice方法
    为什么不用definedProperty 如果数组的项太多,很浪费性能
    const data = { arr: [1, 2, 3] }; const arrayOrigin = Array.protptype; const arrayMethods = Object.create(arrayOrigin); // 不是深拷贝 function definedReactive(obj) { for (const prop in obj) { let value = obj[prop]; if (a.constructor === Array) { arrayReactive(value); } else // 非数组响应式用defineProperty } } function arrayReactive(arr) { [‘pop’, ‘push’, ‘shift’, ‘unshift’, ‘splice’, ‘sort’, ‘reverse’].forEach(method => { arrayMehods[method] = function (…args) { // 函数劫持后(即执行原生的数组方法) arrayOrigin[method].apply(this, args); // 再执行自己的函数 render(); } }); arr.proto = arrayMethods; } function render () { app.innerHTML = data.arr; } render(); data.arr.push(4);

    Vue.$set()
    对于数组,是用重写的splice来实现
    对于对象,就是对新增的属性或者修改的属性,重新进行一次defineReactive()
    模板渲染(能答出大概流程和with语法就好了,还要了解虚拟dom)(有余力的可以把diff算法也说一下)
    通过vue-template-compiler包,先将代码解析成AST语法树
    优化代码,对静态节点进行标记
    生成代码字符串,通过with + new Functoin 实现生成render方法,render执行后生成的是虚拟dom
    1.通过vue-template-compiler包,将代码生成ast语法树,对代码进行优化,标记静态节点(如

    123
    )
    2.将ast语法树生成代码字符串,通过with + new Function()实现生成render函数,render执行后生成一个虚拟dom(本质就是一个js对象)
    - with(vm) {}这样在内部就可以直接使用_c,_v,_s,和data中的属性 with(this){return _c(‘div’,[_v(“zf”)])} this就是vm
    从虚拟dom到页面的真实渲染,通过_updateComponent包的vm._update函数传入vnode,利用patch方法生成真实dom节点并渲染到页面
    初次渲染时生成的真实dom结构渲染到容器中,re-render时,利用diff算法比对新旧节点的差异,生成需要更新的真实dom,渲染到容器对应的位置
    附加分
    vue的diff算法是平级(父级比完比儿子,儿子比完比孙子)比较,不考虑跨级比较(即不考虑父亲和儿子的比对);内部采用深度递归的方式+双指针的方式进行比较
    先比较是否是相同节点(主要比较key和标签名)
    相同节点则比较属性,并复用老节点
    比较儿子节点,考虑老节点和新儿子节点的情况
    优化比较:先比较头头,尾尾,头尾,尾头
    比对查找进行复用
    核心:使用key,key相同直接复用;找不到key则创建元素,多的就删除(vue2,vue3,react都是这样)
    12.讲一下虚拟dom
    虚拟dom就是用js对象来描述真实dom,是真实dom的抽象,因为直接操作dom的话会带来性能消耗,所以通过diff算法来对比差异进行更新dom,可以减少对真实dom的操作;并且虚拟dom不依赖真实平台环境,可以实现跨平台使用。
    虚拟dom的实现就是普通对象包含tag,data,children等属性对真实节点的描述本质就是在js和dom之间的一个缓存
    跨域(还有关于跨域的其他问题,忘记了。。。)
    跨域请求资源
    文件,css文件,jpg,png等,都允许被跨域,src属性的资源也允许被跨域,href的大部分资源都允许被跨域算跨域请求的资源:后端接口的数据、其他域的cookie、其他域的缓存跨域行为发生在哪里:即使跨域了,请求也可以发出,服务器也可以收到请求并且正常处理,然后返回数据,浏览器也能正常接收数据,接收到之后,根据同源策略,检查当前域和请求的域是否相同,如果不同则为跨域,返回数据就不会传递给我们的代码解决跨域:jsonp(需要后端配合)、后端设置Access-Control-Allow-Origin属性以支持跨域;后端不配合时:iframe(只能显示,不能操作)、通过反向代理,比如vue的proxy虚拟代理,在本地模拟一个代理服务器
    webpack编译原理
    初始化
    读取配置文件,合并配置对象
    编译
    检查模块文件是否有记录,有则用记录的,没有则继续
    读取文件内容
    构建ast语法树
    记录依赖,并存入dependencies依赖集中
    替换依赖函数
    将转换后的模块代码保存起来(每个模块代码对应一个唯一的模块id)
    递归加载依赖集中的模块
    输出
    生成相应的资源文件
    webpack性能优化
    构建性能
    减少模块解析,如一些没有依赖的模块,比如jquery,lodash
    配置module.noParse,被匹配到的模块不会解析,如
    module: {
    noParse: /jquery/
    }
    优化loader性能,如lodash,jquery不需要转换,所以他们不需要loader
    热替换,降低代码改动到页面呈现的时间
    devServe: {
    hot: true
    }
    传输性能
    减少打包后的js代码传输到浏览器的时间,即压缩打包体积或者分块打包
    分包
    手动分包将公共模块单独打包出来
    自动分包,配置合理的分包策略,webpack内部是使用SplitChunksPlugin进行分包的
    单模块体积优化,代码压缩(UglifyJsPlugin),tree-shaking(消除模块中未引用的依赖和代码)
    运行性能
    书写高性能代码(一般在项目完成后进行此优化)
    webpack热更新原理,底层实现(主要是我简历写了熟悉webpack,问的有点深,懵逼了)
    我只答了缓存
    欲了解的自己百度一下hh
    class和原型继承的区别
    这个我考虑了一下说没有区别,就是代码简洁了
    百度一下好像也是没有实质的区别,望补充
    讲一下ajax
    就讲自己的理解吧,自由发挥
    讲一下闭包
    应用
    自执行函数
    自己发挥hh
    坏处
    内存泄漏
    js的垃圾回收机制
    标记
    清除
    如何解决内存泄漏,大型项目又咋办
    控制台工具有个memory还是performance来着
    自己百度一下哈
    事件委托
    通过哪个属性来获取目标对象
    委托对象的target属性
    二面
    如何禁用缓存
    cache-control的no-store(顺便讲一下no-store和no-cache的区别)
    meta标签的content属性设置为no-cache
    他们两者的优先级谁更高(这个我答不出了,网上暂时还没找到)
    vue2和vue3的响应式处理,有什么区别,从哪些方面进行了优化
    先讲vue2响应式的缺点
    vue3用proxy代理对象,具体大家百度哈
    这个问题连续两个公司的二面都问到,要关注vue3的变化
    如何在jquery上扩展插件
    jQuery.extend, jQuery.fn.extend
    内部如何实现(原理,这个我不知道了,以下是百度内容)
    通过jQuery.extend扩展jQuery时,方法被添加到了jQuery构造函数中,而当我们通过jQuery.fn.extend扩展jQuery时,方法被添加到了jQuery原型中
    有没有阅读过框架源码
    说有,他可能就要继续问你
    我说以前可能有,但是应该忘了([狗头]hhh)
    问项目(占了一半二面的时间)
    哪个项目最得意,为什么
    项目还能做什么优化
    从性能考虑,构建性能,传输性能,运行性能
    自己根据自己的项目来说
    做项目遇到什么难题,怎么解决
    尽量说,不要说没有
    项目有什么亮点
    尽量说,不要说没有
    从项目里抽一个技术栈来问
    屏幕共享做算法题
    不要慌,一般会给10几20分钟
    先理解题意,不懂马上问面试官,面试官是希望你做出来的,所以不会刁难你
    如果能写出来,再跟面试官交流能否继续优化一下,可以考虑时间复杂度和空间复杂度
    为什么v-for要带key
    讲一下key的作用,巴拉巴拉你们懂的
    用数组索引作为key好不好,为什么
    不好,如果数组涉及删除或者乱序,会影响渲染结果
    了解diff的讲一下diff中key的好处
    先对比标签和key值,如果一样直接复用老节点,提高效率
    如何做通信,比如聊天室,两人互发消息,让我给个方案
    思考了一下,确实不会
    给个数字,判断它的二进制有没有相邻位,如5是101,没有相邻位,返回false;6是110,有相邻位,返回true
    最简单做法是转二进制然后逐位判断,转二进制可用toString(2),这个api只能转数字类型的数字,不能转字符串类型的数字
    更优算法—位运算
    能想到位运算应该就算通过了
    利用num & 1得到num的最后一位二进制为0或者1,依次判断
    补充:& 1能用来判断奇偶数;| 0和& -1能用来向下取整(详细见一大点中的位运算)
    模拟场景,我是黑客,面试官是用户,我如何进行XSS攻击
    我答了XSS两种类型,存储型和反射型,从这两个类型去思考,一个是利用网站漏洞去注入脚本,一个是诱导用户点击到其他网站
    具体可以看一大点的XSS攻击(一大点真的有用)(一大点真的有用)(一大点真的有用)
    node可以做大型服务器吗,为什么
    看袁老师node课第一章
    用express还是koa
    继续追问中间件(讲中间件的原理)
    有没有自己封装过中间件,有(袁老师node课express中间件课)
    用node写过哪些接口,登录验证是怎么做的
    别问,问就是袁老师的node课(狗头)