【前端面经】热乎的小米面经总结

发表于 3年以前  | 总阅读数:408 次

写在前面

春招已经接近尾声,想必诸多学子也已收获满意的offer。而笔者在与一面阔别大概半个月之久,又收到小米的二面。相对于其他面试,小米更侧重的是你用最简练的语言能够最详细地表述你的想法,最后惯例得两道手撕代码题。

1 自我介绍、项目介绍

2 常规基础题

「2.1 vuex是什么?怎么使⽤?哪种功能场景使⽤它?」

  • 只⽤来读取的状态集中放在store中;改变状态的⽅式是提交mutations,这是个同步的事物;异步逻辑应该封装在action中。
  • 在main.js引⼊store,注⼊。新建了⼀个⽬录store,…export 。
  • 场景有:单⻚应⽤中,组件之间的状态、⾳乐播放、登录状态、加⼊购物⻋
  • state:Vuex 使⽤单⼀状态树,即每个应⽤将仅仅包含⼀个 store 实例,但单⼀状态树和模块化并不冲突。存放的数据状态,不可以直接修改⾥⾯的数据。
  • mutations:mutations 定义的⽅法动态修改 Vuex 的 store 中的状态或数据
  • getters:类似 vue 的计算属性,主要⽤来过滤⼀些数据。
  • action:actions 可以理解为通过将 mutations ⾥⾯处⾥数据的⽅法变成可异步的处理数据的⽅法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发action。

modules:项⽬特别复杂的时候,可以让每⼀个模块拥有⾃⼰的 state、mutation、action、getters,使得结构⾮常清晰,⽅便管理

「2.2 关于响应式数据绑定,双向绑定机制:Object.defineProperty()」

vue实现数据双向绑定主要是:采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应监听回调。当把⼀个普通Javascript对象传给Vue实例来作为它的data选项时,Vue将遍历它的属性,⽤Object.defineProperty()将它们转为getter/setter。⽤户看不到getter/setter,但是在内部它们让Vue追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定将MVVM作为数据绑定的⼊⼝,整合ObserverCompileWatcher三者,通过Observer来监听⾃⼰的model的数据变化,通过Compile来解析编译模板指令(vue中是⽤来解析{{}}),最终利⽤watcher搭起observerCompile之间的通信桥梁,达到数据变化—>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

「数据劫持」:Vue内部使⽤了Object.defineProperty()来实现双向绑定,通过这个函数可以监听到set和get的事件。

var data = { name: 'yck' }
observe(data)
let name = data.name // -> get value
data.name = 'yyy' // -> change value
function observe(obj) {
    // 判断类型
    if (!obj || typeof obj !== 'object') {
     return
    }
    //Object.keys(obj)将对象转为数组
    Object.keys(obj).forEach(key => {
     defineReactive(obj, key, obj[key])
    })
}
function defineReactive(obj, key, val) {
    // 递归⼦属性
    observe(val)
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            console.log('get value')
            return val
        },
        set: function reactiveSetter(newVal) {
            console.log('change value')
            val = newVal
        }
    })
}

「Proxy 与 Object.defineProperty 对⽐」

Object.defineProperty 虽然已经能够实现双向绑定了,但是他还是有缺陷的 .

  • 只能对属性进⾏数据劫持,所以需要深度遍历整个对象 对于数组不能监听到数据的变化
  • 虽然 Vue 中确实能检测到数组数据的变化,但是其实是使⽤了 hack 的办法,并且也是有缺陷的。

「web网站中常见攻击手法和原理」

  • 跨站脚本攻击(xss):恶意攻击者通过往web页面中插入恶意html代码,当用户浏览该页面时,嵌入web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。
  • sql注入:sql注入就是把sql命令插入到web表单进行提交,或输入域名,或页面请求的查询字符串,最终达到欺骗服务器执行恶意sql命令的目的。具体而言,就是利用现有应用程序,将恶意的sql命令注入到后台数据库引擎中进行执行。
  • cookie攻击:通过js很容易访问到当前网站的cookie,你可以打开任何网站,然后在浏览器地址栏输入javascript:alert(doucment.cookie),立刻可以看到当前站点的cookie,攻击者可以利用这个特性取得用户的关键信息。假设这个网站仅依赖cookie进行用户身份验证,那么攻击者就可以假冒你的身份来做一些事情。现在多数浏览器都支持在cookie上打上HttpOnly的标记,但凡有这个标记的cookie就无法通过js来获取,如果能够在关键cookie上打上标记,就可增强cookie的安全性。
  • HTTP Headers攻击:凡是用浏览器查看任何web网站,无论你的web网站采用何种技术和框架,都用到了http协议。http协议在Response headercontent之间,有一个空行,即两组CRLF(0x0D 0A)字符这个空行标志着headers的结束和content的开始。攻击者利用这一点,只要攻击者有办法将任意字符注入到headers中,这种攻击就可以发生。
  • 文件上传攻击:文件上传漏洞就是利用对用户上传的文件类型判断不完善,导致攻击者上传非法类型的文件,从而对网站进行攻击。比如可以上传一个网页木马,如果存放文件的目录刚好有执行脚本的权限,那么攻击者就可以得到一个webshell

「Vue中diff原理」

要知道渲染真实DOM的开销是很大的,比如有时候我们修改了某个数据,如果直接渲染到真实dom上会引起整个dom树的重绘和重排。有没有可能我们只更新我们修改的那一小块dom而不要更新整个dom呢?diff算法能够帮助我们

「diff算法包括一下几个步骤:」

  • JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中
  • 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较(diff),记录两棵树差异
  • 把2所记录的差异应用到步骤1所构建的真正的DOM树上(patch),视图就更新了

diff算法是通过「同层的树节点」进行比较而非对树进行逐层搜索遍历的方式,所以时间复杂度只有O(n),是一种相当高效的算法 逐个遍历newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。遍历完成之后如果oldVdom中还有没处理过的节点,则说明这些节点在newVdom中被删除了,删除它们即可。

「vue模板编译原理」

模板转换成视图的过程整个过程:

  • Vue.js通过编译将template 模板转换成渲染函数(render ) ,执行渲染函数就可以得到一个虚拟节点树
  • 在对 Model 进行操作的时候,会触发对应 Dep 中的 Watcher 对象。Watcher 对象会调用对应的 update 来修改视图。这个过程主要是将新旧虚拟节点进行差异对比,然后根据对比结果进行DOM操作来更新视图。 我们对上图几个概念加以解释:
  • 渲染函数:渲染函数是用来生成Virtual DOM的。Vue推荐使用模板来构建我们的应用界面,在底层实现中Vue会将模板编译成渲染函数,当然我们也可以不写模板,直接写渲染函数,以获得更好的控制。
  • VNode虚拟节点:它可以代表一个真实的dom节点。通过createElement方法能将VNode渲染成dom节点。简单地说,vnode可以理解成节点描述对象,它描述了应该怎样去创建真实的DOM节点。
  • patch(也叫做patching算法):虚拟DOM最核心的部分,它可以将vnode渲染成真实的DOM,这个过程是对比新旧虚拟节点之间有哪些不同,然后根据对比结果找出需要更新的的节点进行更新。这点我们从单词含义就可以看出,patch本身就有补丁、修补的意思,其实际作用是在现有DOM上进行修改来实现更新视图的目的。VueVirtual DOM Patching算法是基于Snabbdom的实现,并在些基础上作了很多的调整和改进。

「介绍下你了解Webpack多少知识」

基本概念:

  • 入口(Entry):指示webpack应该使用哪个模块,来构建其内部依赖图的开始。
  • 加载器(Loader):webpack默认处理js和json文件,loader配置webpack去处理其他类型的文件,将其转为有效模块给应用程序使用,并添加到依赖图中。
  • 插件(Plugins):loader用于转换某些类型的模块,而插件用于执行范围更广的任务。比如:打包优化、资源管理、注入环境变量等。
  • 模式(Mode):设置当前配置文件在开发和生产环境下的优化行为,默认为生产环境。
  • 输出(Output):指示webpack应该在哪输出它创建的bundle,以及如何命名文件。入口文件可以有多个,但是出口文件只能有一个。

Loader和Plugin的区别:

  • 「Loader」module.rules中配置,也就是说他作为模块的解析规则而存在。类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)。
  • 「Plugin」plugins中单独配置。类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

在我的个人理解中,plugin更像是对loader的补充,两者进行相辅相成,loader大多是固定的配置,而plugin能够处理更加灵活的设置。

核心作用:

  • 打包压缩:在进行开发时,项目文件是千姿百态的,此时可以使用Webpack将不同模块有序进行打包整合,根据业务进行进行划分模块,使得结构清晰可读。整个项目在开发过程中,代码和文件是比较庞大的,如果进行项目部署时,会占用很大的内存,因此可以进行压缩,将原先几十M降低成几M,甚至几百K。
  • 编译兼容:相信在实际开发中,由于历史的原因各种浏览器遗留下很多兼容性问题,一方面我们积极学习浏览器的新性能,另一方面又要兼顾旧浏览器的问题。通过Webpack进行按需加载器的机制,可以实现在配置bebel-loader时,对预定义的环境进行配置,将其对新旧浏览器进行兼容。与此同时,由于浏览器只能读取html、js等文件,因此可以通过webpack将非js文件模块转为可读js文件模块。
  • 能力拓展:通过webpackPlugin机制,我们在实现模块化打包和编译兼容的基础上,可以进一步实现诸如按需加载,代码压缩等一系列功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。

3 手撕代码题

3.1 千分位格式化数字

用js实现如下功能,将给定的数字转化成千分位的格式,如把12345678转化成12,345,678

这题目相对是比较简单了,能够用来解决的问题的方法也有很多,最简单的可以用正则化进行处理。

  • 正则化
let num = 12345678;
let str = num.toString();
let newStr = str.replace(/(\d)(?=(?:\d{3})+$)/g,"$1,");
  • 将字符串拆分拼接

思路:将数字转换为字符串(toString())再打散成数组(split),如果直接数字转换为数组,就是一整个放进去了,不能单独取到每一位。然后通过循环,逐个倒着把数组中的元素插入到新数组的开头(unshift),第三次或三的倍数次,插入逗号,最后把新数组拼接成一个字符串。

let num = 12345678;
function Thousands(num){
  //将数字转换为字符串后进行切分为数组
  let numArr = num.toString().split("");
  let arr = [];
  let count = 0;//用于计数
  for(let i = numArr.length-1;i>=0;i--){
    count++;
    //从numArr末尾取出数字后插入arr中,其实就是对齐进行倒序
    arr.unshift(numArr[i]);
    //当count每到三位数字,则进行追加逗号。i!=0即取到第1位的时候,前面不用加逗号。
    if(!(count%3)&&i!==0) arr.unshift(",");
  }
  //将数组拼接为字符串
  return arr.join("");
}
Thousands(num);

缺点:一位一位的加进去,性能差,且还要先转换成字符串再转换成数组。

  • 用charAt()获取子字符串,主要用到字符串拼接

思路:不先转为数组,直接获取字符串的每一个字符进行拼接。

let num = 12345678;
function Thousands(num){
  //将数字转换为字符串
  let str = num.toString();
  let res = "";//用于接收拼接后的新字符串
  let count = 0;//用于计数
  for(let i = str.length-1;i>=0;i--){
    count++;
    //从numArr末尾取出数字后插入arr中,其实就是对齐进行倒序
    res = str.charAt(i) + res;
    //当count每到三位数字,则进行追加逗号。i!=0即取到第1位的时候,前面不用加逗号。
    if(!(count%3)&&i!==0) res = ',' + res;
  }
  //将数组拼接为字符串
  return res;
}
Thousands(num);

缺点:依旧需要进行一一分割拼接。

  • 每截取三位进行拼接

思路:每次取末三位子字符串放到一个新的空字符串里并拼接上之前的末三位,原本数组不断截掉后三位直到长度小于三个,最后把剥完的原数组拼接上新的不断被填充的数组。

let num=123345678;
function Thousands(num){
    //将数字转换为字符串
    let str = num.toString();
    let res = "";//用于接收拼接后的新字符串
    while(str.length>3){
        res = "," + str.slice(-3) + res;
        str = str.slice(0,str.length-3)
    }
    if(str) return str + res;
};
Thousands(num);

3.2 比较两个对象的属性和值是否相同

题目描述:

obj1 = {name:"wenbo",age:12,score:[120,121,113]};
obj2 = {age:12,name:"wenbo",score:[120,121,113]};
  • 遍历进行比较

思路:对两个对象进行遍历取值进行比较

function fun(obj1,obj2){
  //判断obj1、obj2是否为Object类型
  let o1 = obj1 instanceof Object;
  let o2 = obj2 instanceof Object;
  //如果两者有不是对象类型的,既可以直接进行等值比较
  if(!o1 || !o2) return obj1 === obj2;
  //如果两个是对象类型,且两者的键值对个数不同
  if(Object.keys(obj1).length!==Object.keys(obj2).length) return false;
  //当以上情况均不是,则进行遍历比较
  for(let key in obj1){
    //需要判断两个对象的此key对应的值是否为对象类型
    let flag1 = obj1[key] instanceof Object;
    let flag2 = obj2[key] instanceof Object;
    if(flag1 && flag2){
      fun(obj1[key],obj2[key])
    }else if(obj1[key] !== obj2[key]){
      return false;
    }
  }
  return true;
}
let obj1 = {name:"wenbo",age:12,score:[120,121,113]};
let obj2 = {age:12,name:"wenbo",score:[120,121,113]};
fun(obj1,obj2);

亦或:

function fun(obj1,obj2){
  //判断obj1、obj2是否为Object类型
  let o1 = obj1 instanceof Object;
  let o2 = obj2 instanceof Object;
  //如果两者有不是对象类型的,既可以直接进行等值比较
  if(!o1 || !o2) return obj1 === obj2;
  //如果两个是对象类型,且两者的键值对个数不同
  if(Object.keys(obj1).length!==Object.keys(obj2).length) return false;
  //取对象obj1和obj2的属性名
  let obj1Props = Object.getOwnPropertyNames(obj1);
  //循环取出属性名,再判断属性值是否一致
  for (let i = 0; i < obj1Props.length; i++) {
    let propName = obj1Props[i];
    //需要判断两个对象的此key对应的值是否为对象类型
    let flag1 = obj1[propName] instanceof Object;
    let flag2 = obj2[propName] instanceof Object;
    if(flag1 && flag2){
      fun(obj1[propName],obj2[propName])
    }else if(obj1[propName] !== obj2[propName]){
      return false;
    }
  }
  return true;
}
let obj1 = {name:"wenbo",age:12,score:[120,121,113]};
let obj2 = {age:12,name:"wenbo",score:[120,121,113]};
console.log(fun(obj1,obj2));;
  • 需要考虑的问题

当对象遍历过程中,遇到对象的属性时Object类型,且指向的是该对象,那么需要考虑的是以上代码还能运行成功吗?如:

let obj1 = {name:"wenbo",age:12,score:[120,121,113]};
obj1.temp = obj1;
let obj2 = {age:12,name:"wenbo",score:[120,121,113};
obj2.temp = obj1;

思路:新建一个数组,将obj1遍历过的键值存储在数组中,再下一次进行遍历时发现一样的值,直接跳过进行比较。

参考文章

  • 1.《当面试官问Webpack的时候他想知道什么》:https://mp.weixin.qq.com/s/RmcMWzkAiOrOOyxtPSZDUg
  • 2.《webpack的面试题总结》:https://juejin.cn/post/6844903877771264013

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/WleuHH8O_ujI-dO-yo00Kg

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录