前言
本人2年半左右的工作经验,第一份工作是出差比较多(低代码定制化项目,政府、军工、工业等)+ 低代码,第二份是教育行业 Saas 后台和h5相关,干了半年多被裁员了。
只做过 PC 和 h5,没有跨端经验,小程序接触过一点,但也相当于是小程序里面写点业务逻辑。
https的理解
因为不知道从哪方面说,我就说了 https 和 http 的区别
然后说到了安全性和加密,然后面试官就问我加密相关的了
HTTP和HTTPS协议的主要区别如下:
- HTTPS协议需要CA证书,费用较高;而HTTP协议不需要;
- HTTP协议是超文本传输协议,信息是明文传输的,HTTPS则是具有安全性的SSL加密传输协议;
- 使用不同的连接方式,端口也不同,HTTP协议端口是80,HTTPS协议端口是443;
- HTTP协议连接很简单,是无状态的;HTTPS协议是有SSL和HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP更加安全。
https加密后会不会被攻击?有了解过吗?
回答:没了解过
现在了解了
首先就是非对称加密它会被中间人攻击,图示如下:
你说到了数字证书,可以详细说说吗
回答:没有深入了解过(这个时候是最开始的几个问题,都没回答上或者没回答好,已经心灰意冷了OTZ)
关于 HTTPS 的部分就看这篇文章吧:看图学HTTPS
可以说说浏览器渲染相关的吗?
回答:
1.请求后,通过HTML文件得到DOM树
2.css得到规则树
3.DOM树+CSS树得到渲染树
4.重排重绘到页面上
你提到了渲染树,你能不能详细说说渲染树?
语无伦次的说了些自己认为的(没深入了解过,GG)
详情看这篇文章,浏览器相关知识很详细:浏览器从输入URL到页面渲染加载的过程(浏览器知识体系整理)
手写一个防抖
太紧张了,第一次面大厂,脑子一片空白,居然没写出来,想死了
function debounce(fn,delay){
let timer = null;
return function(...args){
if (timer) clearoutTimer(timer)
timer = setTimeout(() => fn(...args), delay);
}
简单实现一个 EventMitter
稍微没那么紧张,只写了个大概思路,而且写的还有问题....这里复盘一下,想死
class EventEmitter {
constructor() {
this.event = {
//key: arr 的形式
}
}
add(name, callback) {
// 没订阅过
if (!this.event[name]) {
this.event[name] = []
}
// 把回调加到对应函数
this.event[name].push(callback)
}
delete(name, callback) {
// 判断有没有订阅过之前
if (!this.event[name]) {
this.event[name] = []
}
// 过滤掉 name 函数中不是 callback 的回调
this.event[name] = this.event[name].filter(eve => eve !== callback);
}
play(name) {
// 拿到 name 函数中所有的回调
const callbacks = this.event[name]
// 调用所有回调
callbacks.forEach(eve => {
eve?.()
});
}
}
React Diff 怎么做的?
说的时候说到一半面试官就打断了,说大概知道我想说什么。 然后又提到了 fiber,就继续问了 fiber
说说你对Fiber的理解
React做了哪些性能优化
回答:usecallback usememo memo 这些
然后问了什么时候会做以及为什么要这样做
这个就根据平时项目 + 自己的理解说了下,面试官也没继续深入了
# memo、useMemo、useCallback 你真的用明白了吗
项目里面React用了哪些hooks?
就把常用的说了
然后问了下 useEffect
useEffect 是什么时候执行的
这个我印象中有,类似于vue里面生命周期的 挂载阶段执行的,然后又继续问了
useLayoutEffect用过没?
实际项目确实没用过,然后问了下跟 useEffect 的区别
我记得 layoutEffect 是DOM挂载前,useEffect 是挂载后,然后就没问了
visibilty: hidden 和 display: none 的区别
可能是前面答的都不怎么好,所以问了个基础的
回答:前者隐藏后占据文档,后者不会;
项目里面 visibilty: hidden 和 display: none 哪个用的多?
回答:display 用的多
然后面试官问为什么,我也没想过为什么,然后从性能优化方面补了一句
回答:前者不会引起重排,只重绘
然后就没多问了
有一个场景,发送多次请求,怎么保证参数与请求对应
给的场景题,一个输入框,不小心发了两次请求,怎么保证请求和对应的参数一致
实际项目里面我没遇到过,所以当时也不知道解决办法
然后说了下避免这种情况发生,会用防抖节流这种优化
然后现在能想到的思路是:取消之前的请求或者在请求发出前保存当前请求的参数,在请求完成时比较参数,如果参数不一致则忽略响应
不知道有没有大佬来解惑一下
import React, { useState, useRef, useEffect } from 'react';
import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;
const SearchComponent = () => {
const [searchTerm, setSearchTerm] = useState('');
const [loading, setLoading] = useState(false);
const [results, setResults] = useState([]);
const searchRef = useRef(null);
const handleSearch = async (event) => {
event.preventDefault();
// 保存当前输入框的值
const currentSearchTerm = searchTerm;
// 如果存在 cancel,就取消发送
if (cancel) {
cancel('Request canceled due to new search');
}
// 如果没有 cancel,通过 axios 的 cancelToken 整一个
cancel = new CancelToken((c) => {
cancel = c;
});
setLoading(true);
try {
const response = await axios.get('/api/search', {
params: { q: searchTerm },
cancelToken: cancel,
});
// 比较当前这个请求和输入框的值是不是一样的,是我才响应
if (currentSearchTerm === searchTerm) {
setResults(response.data);
}
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message);
} else {
console.error('Error fetching search results:', error);
}
} finally {
setLoading(false);
}
};
const handleChange = (event) => {
setSearchTerm(event.target.value);
};
return (
<div>
<form onSubmit={handleSearch}>
<input
type="text"
value={searchTerm}
onChange={handleChange}
ref={searchRef}
placeholder="Search..."
/>
<button type="submit" disabled={loading}>
{loading ? 'Searching...' : 'Search'}
</button>
</form>
{loading && <p>Loading...</p>}
{results.length > 0 && (
<ul>
{results.map((result, index) => (
<li key={index}>{result}</li>
))}
</ul>
)}
</div>
);
};
export default SearchComponent;
说下闭包吧
闭包的话看这篇# JS高频面试题合集(自用,持续更新...)
理论说完了之后然后问了下实际项目里面有没有用过闭包
说真的一时半会儿想不起来,所以就说的没有
EventLoop
# 前端进阶:看完就清楚的 JS EvenetLoop(事件循环)
微任务 宏任务你知道哪些
比如:
- Promise.then():微任务
- setTimeOut:宏任务
- async、await:微任务
- setInterval:宏任务
只说了这几个常见的微任务
你怎么定义微任务和宏任务的
这个确实没想过,就说的是学习过程中去记
然后面试官说发一个请求算哪种?
我说微任务,比如 async await 返回的 promise 嘛,promise.then 里面处理数据就是微任务,然后就没问了
后记
还根据简历上问了一些工作经历的问题
我的简历写了做了重构组件、历史遗留问题处理,就问了下怎么做重构的
还问了怎么保证重构的质量、性能(这个确实没考虑过,因为代码都太屎了,几千行的代码,优化的时候都是尽量拆分,然后把注释写清楚,保证业务先上线再说)
整个面试过程差不多一个小时吧,能回答上的也就只是能回答上,再深入一点就不知道了,不知道的是真一点不知道
只能说大厂有作为大厂的理由,诶,愿掘友们都能面上大厂