面试题集训3
# 第一家公司
# 概况
- 公司:坐标深圳。
- 面试官:挺能引导回答的一位老哥。
- 面试结果:没戏。
- 面试感受:题目答的不是很好,但是面试大哥能引导我做出一些回答,面试过程感觉还行。
# 面试题
- 请简述从输入
URL
到页面渲染的完成过程。 - 移动端
1px
解决方案。 - 请简述
rem
布局的实现原理和方案。 - 公司有个项目。该项目需要做成单页应用,此时在不使用其他框架的情况下,说一下你该如何实现这个单页应用。
Vue3
中,如何监听数组的变化?为什么要用Proxy
替换defineProperty
?Array(100).map(x=>1)
结果是多少?如何生成100个元素为1的数组?Webpack
如何优化项目体积。- 假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步或两步,计算共有多少种走法?
- 如何优化单页面项目首次加载白屏?
- 项目中比较难忘的事情。
# 请简述从输入URL到页面渲染的完成过程。
这里问的应该是渲染过程,答案可以看三元大神的这篇文章(这么多内容,光是这一题就够折腾😹)
# 移动端1px解决方案。
当时就讲了一个伪类实现,太菜了。
- 0.5px 方案
- 伪类+transform
- viewport + rem
- border-image
- background-image
- postcss-write-svg
# 请简述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*/
2
3
4
5
那么问题来了?怎么让html
元素字体大小恒等于屏幕的1/10呢?如ipone6宽是375px,font-size:37.5px;
html {fons-size: width / 10}
div {width: 5rem} /* 5rem = 5a = 屏幕宽度的50% */
2
我们用js很容易动态的设置html
的font-size
恒等屏幕的1/10;我们可以在页面dom
、 ready
、resize
和屏幕旋转中设置:
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}*/
}
2
3
4
5
6
7
8
9
实现方案
# 公司有个项目。该项目需要做成单页应用,此时在不使用其他框架的情况下,说一下你该如何实现这个单页应用。
web-component Web Components 入门实例教程 (opens new window)
hashchange JS原生一步步实现前端路由和单页面应用 (opens new window)
# Vue3中,如何监听数组的变化?为什么要用Proxy替换defineProperty?
Vue3
通过Proxy实现对数据的监听,可以把v2 v3的双向数据绑定原理讲一遍。Proxy
与Object.defineProperty
方式相比有以下优势:
Proxy
有多达13种拦截方法。- 可以监听数组对象变化
- 代码更简化
- 性能更优秀,
Proxy
返回的是一个新对象,我们可以只操作新对象达到目的,不需要深度遍历监听,性能高于Object.defineProperty
,而Object.defineProperty
只能遍历对象属性直接修改。
# Array(100).map(x=>1)结果是多少?如何生成100个元素为1的数组?
- 数组长度为100的空数组,
map
返回的长度和原数组长度是一致的。 - 如何生成100个元素为1的数组?
Array(100).fill(1)
- 循环
'100个1'.split('')
- 期待其他答案
# Webpack如何优化项目体积。
Scope Hoisting
Tree-shaking
- 公共资源分离
- 图片压缩
- 动态
Polyfill
# 假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步或两步,计算共有多少种走法?
斐波那契数列有一个特征就是 这个数列从第3项开始,每一项都等于前两项之和。
最简单的解法就是递归😂,but,n超过50就很慢了,100标签页直接卡死。
算法的话,可以看看下面的文章,这里不过多描述。
function climbStairs(n) {
return n < 3 ? n : climbStairs(n-1) + climbStairs(n-2)
};
2
3
# 如何优化单页面项目首次加载白屏?
- 优化项目体积
- 路由按需加载
- 开启
gzip
- 图片懒加载
index.html
加loadingui
组件按需加载- 打包后的项目,除了
index.html
,其他全放cdn,不过这个需要开发的时候配置一下 - 骨架屏,这里面试官有提到,用
Webpack
统一处理骨架屏 page-skeleton-webpack-plugin (opens new window)
# 项目中比较难忘的事情
# 第二家公司
# 概况
- 公司:坐标深圳,上市公司,招人做后台管理。
- 面试官:居然是老乡。
- 面试结果:没戏。
- 面试感受:不咋样,不会就过的那种,回答了的也不知道答没答错😹。
# 面试题
this
的指向,严格模式下this
指向,箭头函数this
指向。- 大文件切片上传,一起上传还是单个上传,其中一个失败了如何处理。
- 后台管理系统权限设计。
- 短链接如何实现,使用八位随机字符串匹配(大小写加数字),有多少概率重复。
- 301和302的区别。
- 和=区别。
undefined==false
。1+undefined
。- 合并两个对象,相同的
key
如何处理的。 - 判断空对象。
- 立即执行函数有什么用途。
call、bind、apply
区别。- 函数里面如何获取所有参数。
- 类数组如何转换成真数组。
vue
组件通信方式。vuex
实现原理。
# this的指向,严格模式下this指向,箭头函数this指向
- 默认绑定(非严格模式下this指向全局对象, 严格模式下
this
会绑定到undefined
) - 隐式绑定(当函数引用有上下文对象时, 如
obj.foo()
的调用方式,foo
内的this
指向obj
) - 显示绑定(通过
call()
或者apply()
方法直接指定this
的绑定对象, 如foo.call(obj)
) new
绑定- 箭头函数绑定(
this
的指向由外层作用域决定的)
# 大文件切片上传,一起上传还是单个上传,其中一个失败了如何处理
多个切片一起上传,前端告诉后端切片数量,以及给后端一个上传完成的通知,后端如果发现缺少切片,通知前端续传。
# 后台管理系统权限设计
根据自己接触的项目回答的
- 一共四个表,接口表、菜单表、用户组表、用户表。
- 数据库录入每一个需要权限的接口,并分配一个唯一id。
- 数据库录入菜单,并分配一个唯一id。
- 创建用户组,给用户组非配接口和菜单权限。
- 给用户分配用户组。
- 用户登录的时候拿到菜单权限,通过
addRoutes
动态生成菜单。 - 拿到接口权限,通过自定义指令控制按钮权限。
- 后端返回权限给前端时,同时在redis里面存一份方便权限查询,然后在中间件进行请求拦截。
之前写的一个小玩意,用到了这种权限管理方法,感兴趣的可以看看 https://github.com/taosiqi/uni-head
# 短链接如何实现,使用八位随机字符串匹配(大小写加数字),有多少个?
找一个短点域名做中转,携带8为随机字符串进行匹配。62个字符生成随机8位有多少个 62^8=218340105584896
# 301和302的区别
官方说法
301 redirect: 301 代表永久性转移(Permanently Moved)。
302 redirect: 302 代表暂时性转移(Temporarily Moved )。
301
重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。
302
重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址。
# 和=区别
简单来说: == 代表相同, ===代表严格相同。
最好是先刷一遍这篇文章 undefined!=false之解 及==比较的规则 (opens new window)
==:
如果两个值类型相同,再进行三个等号(===)的比较。
如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:
- 如果一个是null,一个是undefined,那么相等。
- NaN==NaN返回false(注意:Object.is(NaN,NaN)为true)
Number,Boolean,String,Undefined
这几种基本类型混合比较时,会将其转换成数字再进行比较 。 ===:
如果类型不同,就一定不相等。
如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。判断一个值是否是NaN,只能使用isNaN() 来判断。
如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。
如果两个值都是true,或是false,那么相等。
如果两个值都引用同一个对象或是函数,那么相等,否则不相等。
如果两个值都是null,或是undefined,那么相等。
第三篇: JS数据类型之问—转换篇 (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上) (opens new window)
# undefined==false
类型转换是真的要我的老命,这两题都回答错了,下面的解释不知道对不对,有错误请大佬们提出 。
Number,Boolean,String,Undefined
这几种基本类型混合比较时,会将其转换成数字再进行比较
Undefined==false
两边都会转换成数字
Undefined`转成数字是`NaN
false
转成数字为0
NAN==0?
结果 false
这篇文章讲的比较好
# 1+undefined
这里有解释 http://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
的指向对象。
不同点
call
和bind
的参数是直接放进去的,第二第三第 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
状态管理实现通信
# vuex实现原理
[Vuex原理 浅析] (opens new window)
# 面试题
npm
私有仓库搭建【简历有写】。ui
组件库开发,版本不兼容怎么处理- 系统权限设计,接口权限那里配置的【简历有写】。
- 介绍下
WebSocket
- 大文件上传怎么做的【简历有写】。
- 小程序分包,支付流程,手机号码,
setData
大数据优化手段 this
的指向call、bind、apply
- 做过
app
内嵌h5
没,js和原生通信如何处理的? - 介绍下
vue keep-live
- vue数据响应式原理
- 做过
vue3
的项目没【简历有写】。 - 介绍下
vue3 composition-api
ref
和reactive
有什么不一样JS
数据类型- 过什么
es6
语法 - 数据类型判断
- 深拷贝
Promise
有几种状态EventLoop
- 原型链是什么
- 项目里面做过什么优化
- 前后端如何联调
- 短链接平台如何实现【简历有写】。
# npm私有仓库搭建
# 系统权限设计,接口权限那里配置的
- 系统权限设计,根据自己接触的项目回答的。
- 一共四个表,接口表、菜单表、用户组表、用户表。
- 数据库录入每一个需要权限的接口,并分配一个唯一id。
- 数据库录入菜单,并分配一个唯一id。
- 创建用户组,给用户组非配接口和菜单权限。
- 给用户分配用户组。
- 用户登录的时候拿到菜单权限,通过
addRoutes
动态生成菜单。 - 拿到接口权限,通过自定义指令控制按钮权限。
- 后端返回权限给前端时,同时在redis里面存一份方便权限查询,然后在中间件进行请求拦截。
之前写的一个小玩意,用到了这种权限管理方法,感兴趣的可以看看 https://github.com/taosiqi/uni-head
- 接口权限哪里配置的 有超级管理员账户,他拥有配置权限的权限。
# ui组件库开发,版本不兼容怎么处理
不兼容提升组件库大版本就行
# 介绍下WebSocket
主要讲了他两三个特点,以及工作中哪里用到了它。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
其他特点包括:
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是
ws
(如果加密,则为wss
),服务器网址就是 URL。- 阮一峰WebSocket 教程 (opens new window)
# 大文件上传怎么做的
# 小程序分包,支付流程,手机号码,setData大数据优化手段
感觉简历写了小程序,这几个问题都有可能问到。
小程序分包 文档直达 (opens new window)
setData大数据优化手段,可以只修改变化了的数据(^^) 微信小程序setData数据太大解决方案 (opens new window)
# this的指向
- 默认绑定(非严格模式下this指向全局对象, 严格模式下
this
会绑定到undefined
) - 隐式绑定(当函数引用有上下文对象时, 如
obj.foo()
的调用方式,foo
内的this
指向obj
) - 显示绑定(通过
call()
或者apply()
方法直接指定this
的绑定对象, 如foo.call(obj)
) new
绑定- 箭头函数绑定(
this
的指向由外层作用域决定的)
# call、bind、apply
相同点
- 都是改变
this
指向 - 第一个参数都是
this
的指向对象。
不同点
call
和bind
的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 。apply
的所有参数都放在一个数组里面obj.myFun.apply(db,['成都', ..., 'string' ])
。bind
返回的是一个函数,需要手动调用执行,其他参数和call
一样。
# 做过app内嵌h5没,js和原生通信如何处理的?
做过
原生通信不太懂,也没找到写的很好的文章,期待你的回答
# 介绍下vue keep-live
- Props:
- include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。
- 用法:
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和<transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。- 它有
activated
和deactivated
两个生命周期。如<keep-alive>
包裹两个组件:组件A和组件B。当第一次切换到组件A时,组件A的created
和activated
生命周期函数都会被执行,切换到组件B,这时组件A的deactivated
的生命周期函数会被触发;在切换回组件A,组件A的activated
生命周期函数会被触发,但是它的created
生命周期函数不会被触发了。
# vue数据响应式原理
# 做过vue3的项目没
目前在写vue3+ts
的脚手架工具
https://github.com/taosiqi/v3ts-template
# 介绍下vue3 composition-api
# ref和reactive有什么不一样
ref、reactive
是Vue3
中实现响应式数据的方法 ,Vue2
中通过defineProperty
实现,Vue3
通过ES6
的Proxy
实现的。
reactive
- 接受引用类型的参数,返回其
Proxy
,无法响应对整个Proxy
的赋值。
let person = reactive({ name: 'Tom' })
person = { name: 'Tony' } //视图不会更新
person.name = 'Tony' //会更新
2
3
- 使用场景: 不需要赋值操作的数据,结构较深的引用类型(建议)。
- 两者在引用类型的处理上,区别在
ref
拥有value
的包裹,内部则一致。 ref - 接受一个
any
类型的参数,返回{value:''}
包裹的Proxy
,可以通过改变value
属性实现响应式的赋值操作。 ref
的底层本质还是reactive
,系统会根据给ref
传入的值将它转换成reactive({value:data})
。- 在
Vue template
中可以直接使用ref
,Vue
会自动添加.value
,在Js
中使用ref
需要.value
。 - 使用场景:适用于需要赋值操作的数据,基本类型(必须)、结构较浅的引用类型(建议)。
# JS 数据类型
这里可以了解一下js的包装类
- Boolean
- String
- Number 原始值不能有属性和方法,当给它们添加属性的时候系统会自动进行包装类并销毁。
let str = new String("小猪佩奇");
let str2="小猪佩奇"
console.log(str.length); //输出4 .length是String自带的属性。
console.log(str2.length); //输出4 会先new String('小猪佩奇)再取.length; 然后delete;
2
3
4
# 用过什么es6语法
Class
- 模块
import
和export
- 箭头函数
- 函数默认参数
...
扩展运输符允许展开数组- 解构
- 字符串模版
Promise
let const
Proxy、Map、Set
# 数据类型判断
# 深拷贝
# Promise有几种状态
总结:
Promise
的状态一经改变就不能再改变。.then
和.catch
都会返回一个新的Promise
。- catch不管被连接到哪里,都能捕获上层未捕捉过的错误。
- 在
Promise
中,返回任意一个非promise
的值都会被包裹成promise
对象,例如return 2
会被包装为return Promise.resolve(2)
。 Promise
的.then
或者.catch
可以被调用多次, 但如果Promise
内部的状态一经改变,并且有了一个值,那么后续每次调用.then
或者.catch
的时候都会直接拿到该值。.then
或者.catch
中return
一个error
对象并不会抛出错误,所以不会被后续的.catch
捕获。.then
或.catch
返回的值不能是promise
本身,否则会造成死循环。.then
或者.catch
的参数期望是函数,传入非函数则会发生值透传。.then
方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为`catch是.then第二个参数的简便写法。.finally
方法也是返回一个Promise
,他在Promise
结束的时候,无论结果为resolved
还是rejected
,都会执行里面的回调函数。
# EventLoop
# 原型链是什么
# 项目里面做过什么优化
- 优化首页加载时间 面试复盘(一):认清现实 (opens new window)
- 编译打包打包使用
vue-cli-plugin-dll
优化 - 提前预加载提高切换路由的体验 preload (opens new window)
- 开启
gzip
压缩,需要服务端支持 runtime.js
处理策略 打包成一个单独的文件放进index.html
- 全局
scss
变量,不需要每个文件import了
# 前后端如何联调
使用Swagger
# 短链接平台如何实现
找一个短点域名做中转,携带8为随机字符串进行匹配。62个字符生成随机8位有多少个 62^8=218340105584896
# 面试题
- 介绍一下自己之前做过的项目。
Vue
的生命周期。Create
和beforeMount
他们两之间有什么区别。Vue
组件通信。v-if
和v-show
的区别以及使用场景。nextTick
的使用场景和作用。Vue
中的key
有什么作用。- 计算属性和
watch
的区别。 - 子元素上下左右居中。
- 生成一条0.5px的线。
- 自适应方案。
rem
和rm
的区别。vw
和百分比有什么区别。- 合并两个数组。
- 数组去重,冒泡排序。
Object
去掉其中一项属性,delete
删除对象有什么影响。- 深浅拷贝。
- 防抖节流 。
- 从0+100怎么实现。
- 一到一百个相同的请求,后面的依赖前面一个的结果,现在要拿到第一百个结果要怎么做。
- 假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步、两步或三步,计算共有多少种走法,怎么打印出所有走法?
# 介绍一下自己之前做过的项目。
你可以回答的更好
# Vue的生命周期。
组件生命周期
new Vue()
,初始化事件和生命周期beforeCreate
($el
和data
都是undefined
)- 初始化数据和方法(
data
和props
的响应式处理,mehods
方法声明) created
($el
是undefined
,修改data
不触发update
)- 判断有没有
el
项(vm.$mount(el)
),判断有没有模板(没有将el外层的HTML当模板),将模板编译成渲染函数,返回虚拟DOM beforeMounted
($el
是虚拟DOM
,修改data
不触发update
)- 创建正式
DOM
替换虚拟DOM
,挂载到页面指定容器显示 mounted
(可操作真实DOM
)- 数据变更
beforeUpdate
- 重新渲染虚拟
DOM
并通过DIFF
算法比较差异更新真实DOM
updated
- 调用
vm.$destory()
beforeDestory
(清理计时器、事件)- 移除数据监听、事件监听和子组件
destoryed
(实例不可用) keep-alive生命周期 被keep-alive
包裹的组件有activated
和deactivated
两个生命周期。如<keep-alive>
包裹两个组件:组件A和组件B。当第一次切换到组件A时,组件A的created
和activated
生命周期函数都会被执行,切换到组件B,这时组件A的deactivated
的生命周期函数会被触发;在切换回组件A,组件A的activated
生命周期函数会被触发,但是它的created
生命周期函数不会被触发了。
# Create和beforeMount他们两之间有什么区别。
同上题
# vue组件通信。
- 父子间通信:父亲提供数据通过属性
props
传给儿子;儿子通过$on
绑父亲的事件,再通过$emit
触发自己的事件(发布订阅) - 利用父子关系
$parent 、 $children
, - 父组件提供数据,子组件注入。
provide 、 inject
,插件用得多。 - ref 获取组件实例,调用组件的属性、方法
- 跨组件通信
Event Bus
(Vue.prototype.bus=newVue
)基于on
与$emit
vuex
状态管理实现通信
# v-if和v-show的区别以及使用场景。
区别
v-if
是删除生成dom
,v-show
是切换dispaly
的状态。
使用场景
v-if
- 某一块代码在运行时条件很少改变,使用
v-if
较好 (v-if
有更高的切换开销) - 在组件上使用
v-if
可触发组件的生命周期函数 - 与
transition
结合使用 当条件变化时该指令可以触发过渡效果(用于动画切换)
v-show
- 需要非常频繁地切换某块代码,使用
v-show
渲染 - 当条件变化时该指令触发过渡效果(用于动画切换)
# nextTick的使用场景和作用。
使用场景
例:一个子组件通过v-if控制隐藏显示<t v-if='show'><t/>
,当修改完显示状态后,立马通过ref去操作子组件的方法,这个时候会报错,原因在于子组件此时可能还未渲染完成,这个时候使用nextTick
可以解决,他会在dom
更新完成之后再去调用。
作用
在下次 DOM
更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
# vue中的key有什么作用。
key
会用在虚拟DOM
算法(diff
算法)中,用来辨别新旧节点。- 不带
key
的时候会最大限度减少元素的变动,尽可能用相同元素。(就地复用) - 带
key
的时候,会基于相同的key
来进行排列。(相同的复用) - 带
key
还能触发过渡效果,以及触发组件的生命周期
# 计算属性和watch的区别。
- 处理数据的场景不同,监听器(
watch
)适合一个数据影响多个数据,计算属性适合一个数据受多个数据影响 - 计算属性有缓存性,计算所得的值如果没有变化不会重复执行,但是
watch
会重复执行 - 监听器选项提供了更通用的方法,适合执行异步操作或较大开销操作的情况
# 子元素上下左右居中。
# 生成一条0.5px的线。
# 自适应方案。
# rem和rm的区别。
rem
是相对于根元素字体大小em
是相对于自身字体大小
# vw和百分比有什么区别。
- 百分比是相对高度,相对于他的父元素而言。
vw
永远都是相对于视窗大小的。
# 合并两个数组。
arr1.concat(arr2)
[...arr1,...arr2]
- 循环
# 数组去重,冒泡排序。
数组去重
1.Array.from(new Set(arr))
2.[...new Set(arr)]
\3. for
循环嵌套,利用splice
去重
\4. 新建数组,利用indexOf
或者includes
去重
\5. 先用sort
排序,然后用一个指针从第0
位开始,配合while
循环去重
冒泡排序
function bubbleSort (arr) {
for (let i = 0; i < arr.length; i++) {
let flag = true;
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
flag = false;
let temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (flag) break;
}
return arr;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这个是优化过后的冒泡排序。用了一个flag
来优化,它的意思是:如果某一次循环中没有交换过元素,那么意味着排序已经完成了。
冒泡排序总会执行
(N-1)+(N-2)+(N-3)+..+2+1
趟,但如果运行到当中某一趟时排序已经完成,或者输入的是一个有序数组,那么后边的比较就都是多余的,为了避免这种情况,我们增加一个flag
,判断排序是否在中途就已经完成(也就是判断有无发生元素交换)
# Object去掉其中一项属性,delete删除对象有什么影响。
delete Object['name']
delete
只能删除自有属性,不会影响原型链上的属性
# 深浅拷贝。
# 防抖节流 。
# 从0+100怎么实现。
1、使用for
循环从1加到100的总和
let sum=0;
for(var i=0;i<=100;i++){
sum+=i;
}
2
3
4
2、使用while
函数从1加到1000的总和
let i=0, sum=0;
while(i<=100){
sum+=i++;
}
2
3
4
# 一到一百个相同的请求,后面的依赖前面一个的结果,现在要拿到第一百个结果要怎么做。
await async
循环
# 假如你在爬楼梯,楼梯一共有N层,但你每次爬楼梯只能走一步、两步或三步,计算共有多少种走法,怎么打印出所有走法?
代码有点多,具体看我写的另一篇文章
# 第二家公司
# 概况
- 公司:在线教育。
- 面试官:一般。
- 面试结果:互相看不上😂。
- 面试感受:你什么技术能匹配这个工资的???。
# 笔试题
http
和https
的区别requestAnimationFrame
的作用。instanceof
的原理localStorage
、sessionStorage
和Cookie
区别。CommonJS
和ES6 Module
的区别。- 内存泄漏场景。
- 一道包含
async、await、setTimeout、Promise
的事件循环题。 React HOC
的作用,解决了什么问题,怎么理解Hook
,解决了什么问题。Vue
什么是渲染函数,尝试写一个简单的。- 给定一个整数数组,找出其中两个数相加等于目标值。
# http和https的区别
Http
是超文本传输协议,数据明文传输。Https
则是具有安全性的SSL
加密传输协议,传输是加密了的。Http
和Https
使用的端口不一样,前者是80
,后者是443
。
# requestAnimationFrame的作用
# instanceof的原理
# localStorage、sessionStorage 和 Cookie 区别
- 数据存储方面:
cookie
在同源的HTTP
请求里,在服务器和客户端来回传递。storage
是本地保存。 - 存储数据大小:
cookie
限制4kb
,storage
约5MB
。 - 数据有效期:
cookie
的有效期与过期时间设置有关(默认是会话),sessionStorage
当前标签页有效,localStorage
始终有效。 - 作用域:
cookie
、localStorage
同源窗口,sessionStorage
当前标签页 - 操作:
cookie
只作为document
的一个属性可获取,没有其他操作方法。storage
有getItem
、setItem
、removeItem
、clear
等方法。
# CommonJS 和 ES6 Module 的区别
# 内存泄漏场景
# 一道包含async、await、setTimeout、Promise的事件循环题
大致是这个样子的一个题目:今日头条async/await面试题执行顺序 (opens new window)
# React HOC的作用,解决了什么问题,怎么理解Hook,解决了什么问题。
没写过react
# Vue什么是渲染函数,尝试写一个简单的
# 给定一个整数数组,找出其中两个数相加等于目标值,要求时间复杂度O(n)
https://leetcode-cn.com/problems/two-sum/
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
* 创建媒介所(字典表Map),遍历数组,匹配符合信息的目标值 taget - currentValue,
* 匹配成功返回两个数值下标,匹配失败就将选手的信息放入媒介所。
*/
var twoSum = function(nums, target) {
if(!nums) return [];
// 创建字典表
const m = new Map();
// 遍历nums数组
for(let i = 0; i < nums.length; i++){
// 获取当前值
const n = nums[i];
// 获取对当前与该值匹配的数值
const n2 = target - nums[i];
// 判断目标值是否在字典中
if(m.has(n2)){
// 是,在返回目标值的坐标和当前数值的坐标
return [m.get(n2),i]
}
// 不在字典中,则放入字典,key为数值,value为下标
m.set(n,i)
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 面试题
- 做过小程序的错误监控没
script
引入一个第三方的脚本,脚本报错了,怎么能拿到他的详细信息。- 小程序生命周期
- (盒子模型)一个大盒子,里面两个小盒子,他们款分别是
50%
,高是100%
,都有一个1px
的边框,这个时候会宽高溢出,怎么处理。 - 上下居中
Webpack
开启按需加载svg
雪碧图怎能做的- 大文件切片上传
- 微信多端用户同意,小程序怎么拿到
unionid
Canvas
实现一个刮刮乐WebSocket
遇到过什么问题
# 做过小程序的错误监控没
# script引入一个第三方的脚本,脚本报错了,怎么能拿到他的详细信息。
我想到的是用onerror
捕捉,但是面试官问如何拿到详细错误,暂时没想到好的手段。
# 小程序生命周期
# (盒子模型)一个大盒子,里面两个小盒子,他们款分别是50%,高是100%,都有一个1px的边框,这个时候会宽高溢出,怎么处理。
切换盒子模型
# 上下居中
和这个差不多
# Webpack开启按需加载
# svg雪碧图怎能做的
# 大文件切片上传
# 微信多端用户统一,小程序怎么拿到unionid
UnionID 机制说明
如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过UnionID
来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的UnionID
是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,UnionID
是相同的。
UnionID获取途径
- 开发者可以直接通过
wx.login + code2Session
获取到该用户UnionID
,无须用户授权。 - 小程序端调用云函数时,可在云函数中通过
cloud.getWXContext
获取UnionID
。
# Canvas实现一个刮刮乐
可以看看这个,和我面试时讲的思路差不多。
# WebSocket遇到过什么问题
ios
切换页面以及锁屏断开连接
# 参考链接
https://www.yuque.com/istao/interview/