从2月底到现在,我面试了超过20家上海各种各样的互联网公司。
按照公司整理了一下面试题。
叮咚买菜(一面挂)
-
水平垂直居中方式
-
只用一个div实现关闭按钮
- 通过伪元素,::before 实现一横,::after 实现一横,border 做一个圆圈;
- 或者使用 unicode 码实现 x
-
箭头函数(箭头函数有没有arguments)
-
父组件中定义一个子组件,子组件中有useEffect(,[]),父组件更新5次,子组件useEffect会执行几次,怎么让它只执行一次?
-
useEffect函数回调的返回值的作用
-
深拷贝,JSON.parse能不能保存正则
-
class component和hook component的差别是什么?
-
react的性能优化/pureComponent
-
组件懒加载
-
首屏优化的方案
-
如果实现一个弹窗组件只需要import一次,就可以在项目各处使用
-
react fiber
-
斐波那契数列防止溢出
美团(一面挂)
console.log(1);
setTimeout(() => {
console.log(2);
Promise.resolve().then(() => {
console.log(3)
});
});
new Promise((resolve, reject) => {
console.log(4)
resolve(5)
}).then((data) => {
console.log(data);
Promise.resolve().then(() => {
console.log(6)
}).then(() => {
console.log(7)
setTimeout(() => {
console.log(8)
}, 0);
});
})
setTimeout(() => {
console.log(9);
})
console.log(10);
以下代码存在什么问题?
props
const c = this.state.a + this.props.b
this.setState({
a: c
})
计算三个数组的差并交集合,要考虑数组数量扩展
const a = [1, 2, 3, 4, 5, 6]
const b = [1, 2, 4, 6, 7, 8]
const c = [1, 3, 5, 7, 8, 9]
交集:[1]
并集:[1, 2, 3, 4, 5, 6, 7, 8, 9]
差集:[9]
angular怎么实现双向数据绑定
js继承实现的方式
首页白屏优化
缓存使用
react setState是不是异步的
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
react 虚拟DOM
DOM diff怎么做的
echarts可视化,一个图表点击,当前图标高亮,让其他图标不高亮
proxy
字节(一面挂)
CSS
- css实现垂直水平居中
- css盒子模型/标准盒子和怪异盒子差别
- css实现三角形
- rem/em/vh/wh的差别
- calc/support/@media
JS
- 熟悉的ES6属性(讲了解构,async,await)
- generator babel之后是什么样子
- promise.all、race
- 实现一下防抖节流函数
HTTP
- 缓存
- 为什么有同源策略(回答csrf攻击等)
- 跨域方案
- HTTP2.0讲一下
算法题
无序数组找第K大个元素
哈罗出行
function Foo(){
getName = function(){ alert(1); }
return this;
}
Foo.getName = function(){ alert(2);}
Foo.prototype.getName = function() { alert(3);};
var gettName = function(){alert(4);};
function getName(){alert(5);}
//以下输出什么
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getNmae();
new new Foo().getName();
喜马拉雅
手写Array.reduce
多次bind能否生效
实现eventEmiter(观察者模式)
手写排序
首屏优化
HTTP缓存
HTTP缓存的优先级
AMD和CMD的差别
小红书
无序数组找第K大个元素,尽可能多方案
[a,b,c]排列组合有多少种,顺序不敏感,ab和ba是一种
首屏性能优化
前端缓存
SSR
爬虫
事件循环
美团
手写JS继承
两列布局,左边固定200px,右边自适应
echarts问题,如何设置
setState,直接引用this.state的问题,以及解决方法
模块加载,AMD和CMD的差别
事件循环
首屏加载优化
弹窗组件怎么设计
计算三个数组和差集,并集和交集
携程
手写JS几种继承方式,指明优缺点
宏任务:两个代码输出是否相同
//代码1
<script>
console.log(a);
</script>
<script>
console.log('a');
</script>
//代码 2
<script>
console.log(a);
console.log('a');
</script>
考察包装类
var a = 12;
a.x = 2;
console.log(a.x);
算法题:
CSS
实现透明度为0.6的蒙层,蒙层内文字颜色为#fff,蒙层包含淡入淡出动画
三栏布局,左右边固定200px,中间自适应宽度,尽可能多种写法
未知宽高元素垂直水平居中,尽可能多种写法
跨域如何携带cookie
事件循环宏任务会不会互相干扰,js代码和渲染是不是在同一个线程调度?
redux和react-redux的实现原理
百度
手写图片懒加载
route路由原理/hashChange和history
如何做单元测试
H5调试手机代理
数组扁平化,[1,2,3,[4,5,6]]转成[1,2,3,4,5,6]
手写promise.all
position fix失效场景
rem,em,vh,vw的区别
实现0.1+0.2===0.3的方法
tree层次遍历反转
途虎
angular依赖注入和控制反转
flutter三棵树
虚拟滚动实现
事件循环
promise.all手写
300m大文件网络传输优化
网络层中在哪一层知道文件是否传输结束?
特赞
var/let/const区别
实现let,let的babel转换
实现一个toast组件
puredependency和dependency
设计一个toast组件
let var const的对比
babel如何实现ES6的let
箭头函数和普通函数对比
Leetcode
- 实现reduce
- 生成1000个6位不重复的验证码,并且相邻数字不可以是重复的
- 生成1000个6位验证码,不重复,并且相邻数字不能重复
- 实现Array.prototype.reduce,函数入参:reduce(arr,fn,start);
- react和angular的区别
- 设计模式
- switchMap/mergeMap/concatMap的差别
- 设计一个推荐搜索的组件(用到switchMap去取消订阅)
食亨
虚拟滚动滚动怎么计算要展示的数据信息
手写节流
tree dfs
垂直水平居中
div的style中,设置width和height,并且加了important,如何修改div的宽高
首屏优化
BFC
水平垂直居中
两列布局,左边定宽
margin塌陷怎么解决
div设置style的宽高和important,怎么写class可以修改其宽高
虚拟滚动的数组数据怎么计算
防抖节流
计算多叉树的最大深度
react diff算法
微软上海(一面挂)
业务场景设计:
列表可以进行增删,列表中item顺序可以拖拽,但是每次更新的时候,表示顺序的order必须是唯一的,如果被使用过更新会报错。
interface Item {
id: string;
order: number; // int32
}
interface DisplayItem {
id: string;
}
function ajax(options: any): Promise<any> {
/**
* It's not necessary to implement this.
* Usage:
* const promise = ajax({
* method: ...,
* url: ...,
* data: { ... }
* });
*/
throw "Not implemented";
}
function save(groupId: string, displayItems: DisplayItem[], oldItems: Item[]): Promise<any> {
/**
* `displayItems` are ordered by the display order.
* `oldItems` are in ascending order by the `order` property.
*
* PUT https://example.com/api/groups/{groupId}/items/{itemId}
* { "order": ... }
*/
function updateGroupItem(itemInfo){
// TODO
}
function createGroupItem(itemInfo):Promise<any>{
}
// create old Item map
let oldItemMap = {};
let orderMap = {};
oldItems.forEach((cur,idx)=>{
oldItemMap[cur.id] = {
curItem:cur,
isDeleted:true,
}
orderMap[cur.order] = idx;
});
let newUniqueOrderMap = {};
Object.keys(orderMap).forEach(cur=>{
let nums = Number(cur);
while(orderMap[nums] !== undefined && newUniqueOrderMap[nums]){
nums = nums - 1000;
}
newUniqueOrderMap[nums];
});
let newUniqueOrderArr = Object.keys(newUniqueOrderMap);
displayItems.forEach((dis,idx)=>{
let old = oldItemMap[dis.id];
if(!old){
const order = newUniqueOrderArr[idx];
// TODO
createGroupItem({
id:dis.id,
order
})
} else{
// 遍历过无须删除
old.isDeleted = false;
if(orderMap[old.curItem.order] !== idx){
const order = newUniqueOrderArr[idx];
// 更新items
// TODO
updateGroupItem({
id:dis.id,
order
})
}
}
})
const deleted = Object.keys(oldItemMap).filter(cur=>oldItemMap[cur].isDeleted);
deleted.forEach(cur=>{
})
throw "Not implemented";
}
才历
ssr的优点和缺点
首页白屏的优化机制
缓存机制,协商缓存和强制缓存的作用,html/js/css文件应该怎么设置缓存方式
react class component,父子组件中,父组件props变化后,子组件的声明周期如何调用
分包加载如何实现/原理和应用,怎么配
虚拟滚动的实现原理以及虚拟滚动的滚动白屏和缓慢像素加载怎么优化
观察者模式
设计实现api请求可以无痛刷新token
云扩
HTTPS的SSL层如何实现
HTTP跨域
CORS跨域怎么实现
GET/post/delete都会进行跨域的option请求吗?一般来说get不会
React和Angular的区别
虚拟滚动
识货
声明提升,那个优先级高
this的指向,优先级,
call,apply的实现,
new的实现,
实现深拷贝,有哪些问题,怎么避免
算法题 传入数字返回平方根
react单项数据流的优缺点
hooks的eslint规则,为什么有这个规则
什么是fiber架构
事件循环eventloop
实现一个promise
eventloop过程
js原型链
js继承
跨域问题
jsonp有什么问题
最近一个做过比较有技术难点的项目
flex布局问题
多行文本省略怎么实现
css伪类的了解
有5个元素,第二行所有间距相等,第一行如图
设计模式的了解
编码原则的了解
https加密过程
蚂蚁保险
/**
* 题目:实现一个Throttle
* 在移动开发中会有触发比较频繁的事件,比如抢购时用户快速点击一个按钮,用户滚动屏幕引起图片的懒加载等;
* 请完成下面函数 throttle:
*/
// method为传入方法,delay为延迟时间;
function throttle (method,delay) {
// do your work
let start = null;
let timeout = null;
return function(...args){
let context = this;
if(!start) {
start = +new Date();
}
let current = +new Date();
if(!timeout){
timeout = setTimeout(()=>{
start = current;
timeout = -1;
method.apply(context,args);
},delay);
}
if(current - start>=delay){
if(timeout && timeout != -1){
clearTimeout(timeout);
}
start = current;
method.apply(context,args);
}
}
}
//使得:
const method = () => console.log('x')
const warppedMethod = throttle(method, 3000);
// 在3s, 6s之后打印 'x'
warppedMethod();
warppedMethod();
setTimeout(() => {
warppedMethod();
}, 2000);
setTimeout(() => {
warppedMethod();
}, 5000);
//题目:实现一个函数,可以将数组转化为树状数据结构
// 入参格式参考:
const arr = [
{ id: 1, name: 'i1' },
{ id: 2, name: 'i2', parentId: 1 },
{ id: 4, name: 'i4', parentId: 3 },
{ id: 3, name: 'i3', parentId: 2 },
{ id: 8, name: 'i8', parentId: 7 }
];
/* 可以将数组转化为树状数据结构,要求程序具有侦测错误输入的能力*/
function buildTree(arr) {
/**
* 此处写代码逻辑
*/
let idMap = {};
let childrenMap = {};
let head = [];
arr.forEach(cur=>{
if(!idMap[cur.id]){
idMap[cur.id] = cur;
}
if(cur.parentId !== undefined ){
if(!childrenMap[cur.parentId]){
childrenMap[cur.parentId] = new Set();
} else {
childrenMap[cur.parentId].add(cur);
}
} else {
head.push(cur);
}
});
if(!head || !head.length){
throw Error('Level 0 does not exist');
}
function getTree(values){
values.forEach(cur=>{
let children = childrenMap[cur.id];
if(children){
cur.children = Array.prototype.slice(children);
// 在tree中被引用过标记为-1
for(let i=0;i<children.length;i++){
idMap[children.get(i)] = -1;
}
getTree(cur.children);
idMap[cur.id] = -1;
// children被使用过的id设置为-1
childrenMap[cur.id] = -1;
}
})
}
getTree(head);
let idUsed = Object.keys(idMap).filter(k=>idMap[k] !== -1);
let childUsed = Object.keys(childrenMap).filter(k=>childrenMap[k] !== -1);
// 在tree中没有被引用的id,或者父节点不存在的id
if(idUsed.length || childUsed.length) {
console.log(idUsed.concat(childUsed));
}
return head;
}
/**
* 题目:lastPromise实现
* 业务需求中,经常有 只需要最后一次请求的结果(比如搜索)编写一个高阶函数,传递旧请求方法(执行后返回 promise),返回一个新方法。
* 连续触发时,若上一次 promise 执行未结束则直接废弃,只有最后一次 promise 会触发then/reject。
*/
/**
* 只有最后一次promise会then与reject
* @param {function} promiseFunction
* promiseFunction 示例: () => fetch('data')
*/
function lastPromise(promiseFunction) {
const cbs = [];
const promiseMap = {};
return new Promise((resolve, reject) => {
cbs.push(resolve);
const p = promiseFunction();
promiseMap[p] = resolve;
p.then(()=>{
if (cbs.indexOf(resolve) !== cbs.length -1) {
return;
}
resolve()
})
});
//todo
}
// 示例
let count = 1;
let promiseFunction = () =>
new Promise(rs =>
window.setTimeout(() => {
rs(count++);
})
);
let lastFn = lastPromise(promiseFunction);
lastFn().then(console.log); // 无输出
lastFn().then(console.log); // 无输出
lastFn().then(console.log); // 3
(args = [{1,2,4}]) => {
let copy = cloneDeep(args);
copy[0].5 = xxxx;
return copy;
}
问了react-visualized
问了immutable.js
tree BFS非递归怎么解决
tree DFS非递归怎么解决