面试复盘(一):认清现实

4,625 阅读11分钟

前言

金三银四,怎么能少了本菜😁😁。正好借此机会好好恶补一下基础,当然,要是能找到一个合适的工作那就更完美啦。接下来会把每天面试的一些题目在掘金复盘,这样能让自己印象更为深刻一些,同时也为正在找工作的小伙伴们,提供一丢丢的帮助。祝大家都能找到money多多的工作💰💰。

情况说明

本菜经验2年左右,投的多为2-3年经验要求的。

第一家公司

概况

  • 公司:坐标深圳。
  • 面试官:挺能引导回答的一位老哥。
  • 面试结果:没戏。
  • 面试感受:题目答的不是很好,但是面试大哥能引导我做出一些回答,面试过程感觉还行。

面试题

  1. 请简述从输入URL到页面渲染的完成过程。
  2. 移动端1px解决方案。
  3. 请简述rem布局的实现原理和方案。
  4. 公司有个项目。该项目需要做成单页应用,此时在不使用其他框架的情况下,说一下你该如何实现这个单页应用。
  5. Vue3中,如何监听数组的变化?为什么要用Proxy替换defineProperty
  6. Array(100).map(x=>1)结果是多少?如何生成100个元素为1的数组?
  7. Webpack如何优化项目体积。
  8. 假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步或两步,计算共有多少种走法?
  9. 如何优化单页面项目首次加载白屏?
  10. 项目中比较难忘的事情。

请简述从输入URL到页面渲染的完成过程。

这里问的应该是渲染过程,答案可以看三元大神的这篇文章(这么多内容,光是这一题就够折腾😹)

(1.6w字)浏览器灵魂之问,请问你能接得住几个?

移动端1px解决方案。

当时就讲了一个伪类实现,太菜了。

  • 0.5px 方案
  • 伪类+transform
  • viewport + rem
  • border-image
  • background-image
  • postcss-write-svg

移动端1px解决方法知多少

请简述rem布局的实现原理和方案。

原理
假设我们将屏幕平均分为10份,每一份宽度用一个a表示,即a=屏幕宽度/10;那么:

div{width: 5a} /* 屏幕宽度的50% */

但是css中没有a这个单位啊?我们可以实现借助rem代替上面的a。如:

html {font-size: 12px}
div {width: 2rem} /* 24px*/

html {font-size: 16px}
div {width: 2rem} /* 32px*/

那么问题来了?怎么让html元素字体大小恒等于屏幕的1/10呢?如ipone6宽是375px,font-size:37.5px;

html {fons-size: width / 10}
div {width: 5rem} /* 5rem = 5a = 屏幕宽度的50% */ 

我们用js很容易动态的设置htmlfont-size恒等屏幕的1/10;我们可以在页面domreadyresize和屏幕旋转中设置:

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + ‘px‘; 

如何把设计稿的像素单位换成以rem为单位呢?可以用一个比例来计算:如设计稿宽度为750px,某个元素量得75px,那么:

75px/750px = 计算所得rem/10rem,所以计算所得rem=75px;所以我们在样式中写width:1rem;实际宽度是75px;同理,如果设计稿总宽度是640px,则1rem=64px。

预处理函数可以简化:

$ue-width: 750; /* 设计稿图的宽度 */

@function px2rem($px) {
  @return #{$px/$ue-width*10}rem;
}

div {
  width: px2rem(100);/*编译后:  p{width:1.5625rem}*/
}

rem布局原理深度理解

实现方案

vue-ydui中rem布局实现方式

公司有个项目。该项目需要做成单页应用,此时在不使用其他框架的情况下,说一下你该如何实现这个单页应用。

web-component Web Components 入门实例教程
hashchange JS原生一步步实现前端路由和单页面应用
history 前端路由实现原理(history)

Vue3中,如何监听数组的变化?为什么要用Proxy替换defineProperty?

  1. Vue3通过Proxy实现对数据的监听,可以把v2 v3的双向数据绑定原理讲一遍。
  2. ProxyObject.defineProperty方式相比有以下优势:
    • Proxy有多达13种拦截方法。
    • 可以监听数组对象变化
    • 代码更简化
    • 性能更优秀,Proxy返回的是一个新对象,我们可以只操作新对象达到目的,不需要深度遍历监听,性能高于Object.defineProperty,而Object.defineProperty只能遍历对象属性直接修改。

Array(100).map(x=>1)结果是多少?如何生成100个元素为1的数组?

  1. 数组长度为100的空数组,map返回的长度和原数组长度是一致的。

  2. 如何生成100个元素为1的数组?

    • Array(100).fill(1)
    • 循环
    • '100个1'.split('')
    • 期待其他答案

Webpack如何优化项目体积。

  • Scope Hoisting
  • Tree-shaking
  • 公共资源分离
  • 图片压缩
  • 动态Polyfill

webpack构建速度和体积优化策略

假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步或两步,计算共有多少种走法?

斐波那契数列有一个特征就是 这个数列从第3项开始,每一项都等于前两项之和。 最简单的解法就是递归😂,but,n超过50就很慢了,100标签页直接卡死。
算法的话,可以看看下面的文章,这里不过多描述。

function climbStairs(n) {
    return n < 3 ? n : climbStairs(n-1) + climbStairs(n-2)
};

百度百科
算法题-爬楼梯【JS实现】

如何优化单页面项目首次加载白屏?

  • 优化项目体积
  • 路由按需加载
  • 开启gzip
  • 图片懒加载
  • index.html加loading
  • ui组件按需加载
  • 打包后的项目,除了index.html,其他全放cdn,不过这个需要开发的时候配置一下
  • 骨架屏,这里面试官有提到,用Webpack统一处理骨架屏 page-skeleton-webpack-plugin

项目中比较难忘的事情

第二家公司

概况

  • 公司:坐标深圳,上市公司,招人做后台管理。
  • 面试官:居然是老乡。
  • 面试结果:没戏。
  • 面试感受:不咋样,不会就过的那种,回答了的也不知道答没答错😹。

面试题

  1. this的指向,严格模式下this指向,箭头函数this指向。
  2. 大文件切片上传,一起上传还是单个上传,其中一个失败了如何处理。
  3. 后台管理系统权限设计。
  4. 短链接如何实现,使用八位随机字符串匹配(大小写加数字),有多少概率重复。
  5. 301和302的区别。
  6. ==和===区别。
  7. undefined==false
  8. 1+undefined
  9. 合并两个对象,相同的key如何处理的。
  10. 判断空对象。
  11. 立即执行函数有什么用途。
  12. call、bind、apply区别。
  13. 函数里面如何获取所有参数。
  14. 类数组如何转换成真数组。
  15. vue组件通信方式。
  16. vuex实现原理。

this的指向,严格模式下this指向,箭头函数this指向

  • 默认绑定(非严格模式下this指向全局对象, 严格模式下this会绑定到undefined)
  • 隐式绑定(当函数引用有上下文对象时, 如 obj.foo()的调用方式, foo内的this指向obj)
  • 显示绑定(通过call()或者apply()方法直接指定this的绑定对象, 如foo.call(obj))
  • new绑定
  • 箭头函数绑定(this的指向由外层作用域决定的)

【建议👍】再来40道this面试题酸爽继续(1.2w字用手整理)

大文件切片上传,一起上传还是单个上传,其中一个失败了如何处理

多个切片一起上传,前端告诉后端切片数量,以及给后端一个上传完成的通知,后端如果发现缺少切片,通知前端续传。

前端大文件上传

后台管理系统权限设计

根据自己接触的项目回答的

  • 一共四个表,接口表、菜单表、用户组表、用户表。
  • 数据库录入每一个需要权限的接口,并分配一个唯一id。
  • 数据库录入菜单,并分配一个唯一id。
  • 创建用户组,给用户组非配接口和菜单权限。
  • 给用户分配用户组。
  • 用户登录的时候拿到菜单权限,通过addRoutes动态生成菜单。
  • 拿到接口权限,通过自定义指令控制按钮权限。
  • 后端返回权限给前端时,同时在redis里面存一份方便权限查询,然后在中间件进行请求拦截。

之前写的一个小玩意,用到了这种权限管理方法,感兴趣的可以看看 github.com/taosiqi/uni…

短链接如何实现,使用八位随机字符串匹配(大小写加数字),有多少个?

找一个短点域名做中转,携带8为随机字符串进行匹配。62个字符生成随机8位有多少个 62^8=218340105584896

301和302的区别

官方说法
301 redirect: 301 代表永久性转移(Permanently Moved)。
302 redirect: 302 代表暂时性转移(Temporarily Moved )。

301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。

302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址。

==和===区别

简单来说: == 代表相同, ===代表严格相同。

最好是先刷一遍这篇文章 undefined!=false之解 及==比较的规则 ==:

  • 如果两个值类型相同,再进行三个等号(===)的比较。
  • 如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:
    • 如果一个是null,一个是undefined,那么相等。
    • NaN==NaN返回false(注意:Object.is(NaN,NaN)为true)
    • Number,Boolean,String,Undefined这几种基本类型混合比较时,会将其转换成数字再进行比较 。 ===:
  • 如果类型不同,就一定不相等。
  • 如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。判断一个值是否是NaN,只能使用isNaN() 来判断。
  • 如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。
  • 如果两个值都是true,或是false,那么相等。
  • 如果两个值都引用同一个对象或是函数,那么相等,否则不相等。
  • 如果两个值都是null,或是undefined,那么相等。

第三篇: JS数据类型之问—转换篇 (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上)

undefined==false

类型转换是真的要我的老命,这两题都回答错了,下面的解释不知道对不对,有错误请大佬们提出 。
Number,Boolean,String,Undefined这几种基本类型混合比较时,会将其转换成数字再进行比较 Undefined==false两边都会转换成数字
Undefined转成数字是NaN
false转成数字为0
NAN==0?
结果 false

这篇文章讲的比较好
undefined!=false之解 及==比较的规则

1+undefined

这里有解释 es5.github.io/#x9.3 (死记?)
Undefined转换成数字后为NaN Null为+0
NaN加任何都是NaN
结果 NaN

合并两个对象,相同的key如何处理的

相同的key,后面一个会覆盖前面一个

  • In 遍历赋值
  • Obj.assign()
  • 拓展运算符

判断空对象

  • Object.keys(obj).length === 0
  • JSON.stringify(data) == "{}"

立即执行函数有什么用途

创建一个独立的作用域,避免变量污染。

call、bind、apply区别

相同点

  • 都是改变this指向
  • 第一个参数都是 this 的指向对象。

不同点

  • callbind 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 。
  • apply 的所有参数都放在一个数组里面 obj.myFun.apply(db,['成都', ..., 'string' ])
  • bind 返回的是一个函数,需要手动调用执行,其他参数和 call 一样。

函数里面如何获取所有参数

arguments 按参数索引包含所有的参数

注意:箭头函数是没有 arguments ,如果在箭头函数中访问 arguments,访问到的 arguments 并不属于箭头函数,而是属于箭头函数外部的“普通”函数

类数组如何转换成真数组

  • ... 运算符
  • Array.from
  • Array.prototype.slice.apply(arguments)

vue组件通信方式

  • 父子间通信:父亲提供数据通过属性 props传给儿子;儿子通过 $on 绑父亲的事件,再通过 $emit 触发自己的事件(发布订阅)

  • 利用父子关系 $parent $children

  • 父组件提供数据,子组件注入。 provide inject ,插件用得多。

  • ref 获取组件实例,调用组件的属性、方法

  • 跨组件通信 Event Bus (Vue.prototype.bus=newVue)基于on与$emit

  • vuex 状态管理实现通信

Vue组件通信

vuex实现原理

Vuex原理 [浅析]

面试复盘(一):面试官「前阿里大佬」果然厉害

结语

首发于语雀文档@is_tao

面试复盘(一):认清现实
面试复盘(二):重拾自信
面试复盘(三):好心态好状态