前言
文章开始之前,先介绍下个人背景,18年普通本科信管专业毕业,到写文章时有一年多经验,主要使用的是vue。
年前本来不打算面试的,才刚开始复习(这个年限的hc比较少),但是恰好遇到腾讯大佬在招人,便试着投了简历,大概3天后收到了面试短信。
面试的部门是微信支付基础架构部,早前就听说微信面试难度很大,轮次很多,但是心里一直有个大厂梦,这次机会不想错过。 跟面试官约的是晚上,恰逢跨年夜。
下班就到了滨海大厦,腾讯的前台小姐姐很好看呀,长相姣好,妆容精致,身高170+。
咳咳,扯远了,开始正题吧
一面(1h,过)
一面出了5道笔试题
实现斐波那契数列
我用的是最简单的递归方法实现的,果不其然,面试官问我怎么进行优化
function Fibo(n){
if(n<=0){
return 0
}
if(n===1){
return 1
}
return Fibo(n-1)+Fibo(n-2)
}
非递归循环实现:
function Fibo(n) {
if (n <= 0) {
return 0
}
if(n == 1) {
return 1
};
let fn_2 = 0
let fn_1 = 1
let fn = 0;
for (let i = 2; i <= n; i++) {
fn = fn_1 + fn_2
fn_2 = fn_1
fn_1 = fn
}
return fn
}
手写冒泡排序
function bubbleSort(arr){
if(!arr.length){
return arr
}
for(let i=0,l=arr.length;i<l-1;i++){
for(let j=1;j<l-1-i;j++){
if(arr[j]>arr[j+1]){
let temp
temp=arr[j+1]
arr[j]=temp
arr[j+1]=arr[j]
}
}
}
return arr
}
实现的是升序还是降序? 升序
怎么实现降序? 将内层循环的if条件语句改为小于号即可
时间复杂度是多少,这个很简单,O(n^2)
手写二叉树的中序遍历
function inOrder(root,arr=[]){
if(root){
inOrder(root.left,arr)
arr.push(root.val)
inOrder(root.right,arr)
}
return arr
}
使用的递归的方式解决,其实还可以考虑非递归的方式,网上有很多实现,不再赘述
判断一个点是否在圆内
直接套用数学公式
function inCircle(cx,cy,x,y,r){
return (cx-x)^2+(cy-y)^2<r^2
}
其中(cx,cy)是点坐标,(x,y)为圆心,r为半径
为什么不用开根号? 巴拉巴拉
实现_.[2,3,4].increase(1).reverse().val()
用原型链继承即可实现,就不列代码了
自我介绍和项目介绍
每个人针对自己的情况介绍,注意介绍的项目一定要非常熟悉,面试官会往死里问的
简历上写了英语听说读写流利,面试官让我来一段英文自我介绍,这个是我的强项
二分查找,时间复杂度和空间复杂度
function binarySearch(arr,val){
if(!arr.length){
return -1
}
let low=0,high=arr.length-1
while(low<=high){
let mid=Math.floor((low+high)/2)
for(let i=0;i<arr.length;i++){
if(arr[i]===val){
return i
}
else if(arr[i]>val){
high=mid-1
}
else{
low=mid+1
}
}
}
}
复杂度是O(nlogn)
绝对定位和相对定位
送分题
/*
** position:relative 相对定位,相对自身定位
** position:absolute 绝对定位,相对于最近的不为static的父级元素定位
*/
vue v-for里的key作用
当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态的列表渲染输出。
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。
sql分页查询
假设是从用户表里查询前10条信息
select * from user limit 0,10
nodejs的应用
- restful api
- 中间件
- 命令行工具
- api代理
- 反向代理
- 前端构建工具
- 平台打包工具
- 操作系统
nodejs的优缺点
优点:
- 异步
- 非阻塞
缺点:
- 不适合CPU密集型应用
但是有了serveless,我们就可以把存在安全风险的,消耗大量CPU计算的任务都迁移到函数计算上
nodejs异步非阻塞的理解
异步是相对于同步而言的,是指不等请求完成就执行下一个动作的行为。同步是指要等待一个操作完成才能执行下一个操作的行为。
非阻塞是线程/进程相关的,它是相对IO而言的,如果执行一个函数后,当前线程仍处于运行状态,就意味当前线程是可以的继续处理其他任务,但要时不时的去看是否返回结果,这就是非阻塞。
一个线程/进程经历的5个状态,创建,就绪,运行,阻塞,终止。其中有个阻塞状态,就是说当线程中调用某个函数,需要IO请求,或者暂时得不到竞争资源,操作系统会把该线程阻塞起来,避免浪费CPU资源,等得到了资源,再变成就绪状态,等待CPU调度运行。 非阻塞相反,在不能得到结果前,函数不会阻塞线程,而会立即返回
难道面试官看我长得可爱,问题变简单了?
是否参加过校招,当时为什么不校招
没,渣本没有信心
二面(接近2h,挂)
大概在两天后,收到了二面通知短信,约在晚上面(心疼扣钱,真是个贫穷的小女孩了)
有两个面试官交替面试,其中有一个说是团队的老大
流程图的功能设计
可以从封装,继承,多态的角度考虑,主要考察的是需求理解能力和代码设计能力,开放性问题,答案有很多,我就不再赘述了
闭包
这个是前端必会的问题。如果有不懂的可以看<<你不知道的JavaScript(上卷)>>,讲解的很详细。
如果一个函数可以访问其他函数作用域的变量,那这个函数就形成了闭包。
function f(){
var a=1
function closure(){
return a
}
return closure
}
闭包优点
- 可以让一个变量保存在内存中,不被垃圾回收机制清除
- 可以避免变量的全局污染
- 可以定义模块,将操作函数暴露到外部,细节隐藏在模块内部
闭包缺点
- 容易造成内存泄漏
- 闭包对性能会产生负面影响,包括处理速度和内存消耗
内存泄漏
如果一个变量长期存在内存里,没有被垃圾回收机制清除,就会产生内存泄漏。
执行上下文
执行上下文可以简单理解为一个对象,它包含三个部分:
- 变量对象
- 作用域链(词法作用域)
- this指向
类型可分为:
- 全局执行上下文
- 函数执行上下文
- eval执行上下文
代码执行过程: 1.创建 全局上下文
2.全局执行上下文逐行自上而下执行。遇到函数时,函数执行上下文被push到执行栈顶层
3.函数执行上下文被激活,成为 active EC, 开始执行函数中的代码,全局执行上下文被挂起
4.函数执行完后,callee 被pop移除出执行栈,控制权交还全局上下文,继续执行
call,bind,apply
这个答上来了,比较简单就不写了,不了解的可以自行搜索
水平垂直居中
水平居中:
- 行内元素:text-align:center
- 块级元素:margin:0 auto
- display:flex+justify-content:center
- position:absolute+left:50%+transform: translateX(-50%)
垂直居中:
- line-height:height
- display:flex+align-items:center
- position:absolute+top:50%+transform: translateY(-50%)
水平垂直居中:
- position: absolute+top: 50%+left: 50%+transform: translate(-50%,-50%)
- display:flex+justify-content:center+align-items:center
方法不只这些,有兴趣的同学可以自己实现
vue的响应式原理
面试常见题,不会的可以搜下
virtual dom的diff原理
虚拟dom的产生是在浏览器的解析阶段开始的,而浏览器的解析又可以分成以下部分:
- html解析形成DOM树
- css解析形成css 对象模型(Css Object Model)
- DOM树和css Object Model合并成render树
- 页面布局(layout)
- 页面绘制(painting)
每次操作真实DOM,浏览器都会从头到尾解析一次浏览器,造成性能的巨大浪费。
为了解决这个问题,产生了虚拟DOM
虚拟DOM是对真实DOM的结构的抽象,它可以将vnode渲染成真实的DOM,通过和真实DOM的diff比较,对比新旧虚拟节点之间有哪些不同,然后根据对比结果找出需要更新的的节点进行更新。
Vue的diff算法是仅在同级的vnode间做diff,递归地进行同级vnode的diff,最终实现整个DOM树的更新。
父子组件传参
- 父传子: prop
- 子传父:$emit
- eventbus
- 跨多层组件:provide/inject
怎么改变一个数组
怎么改变一个对象
怎么改变一个基本类型值
这三个问题过于基础,不了解的可以看vue文档
性能优化
这个问题最好是结合自身项目经验回答
公司的技术架构
这个涉及公司的问题就保密了
数据库索引的实现原理
具体实现请参考附录2
OSI七层模型
面试的时候有点小紧张,没有说全
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层 每一层都可能发散往深层次问,面试官对我的回答不是很满意,没有继续追问
最小堆原理
这个问题没有答上来,面完以后看了不少关于堆的文章,感觉这篇写的比较好 看动画轻松理解「 堆 」
后记
面试是一个发现自身不足的过程,可能是年限原因,考察我的都是基础,我的数据库实现原理方面答得不是很好。面试官的需求是一个不限于前端的技术人员,需要你对数据结构与算法,数据库,编译原理,操作系统等底层都有深层次的了解,并在一个方向专精。
有准备面试的小伙伴可以关注我的项目algorithm-js,涉及到很多面试知识点,包括:
- 红宝书js基础
- 设计模式
- 数据结构和算法
- vue源码剖析
- 你不知道的js读书笔记
- 计算机网络
文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注。
有复习基础知识准备面试的小伙伴可关注我的github博客,你的star✨、点赞和关注是我持续创作的动力!