HTTP
- [缓存相关]
- 讲一讲强缓存和协议缓存?
- 有了【Last-Modified,If-Modified-Since】为何还要有【ETag、If-None-Match】
- 有关 HTTP 缓存的首部字段说一下
- [TCP/IP 相关]
- HTTP 和 TCP 的区别
- TCP 三次握手和四次挥手?以其存在意义。
- 在一次传输中它是如何保证每个数据包之间的顺序的?
- [HTTP 相关]
- HTTP 请求的什么时候用的对称加密什么时候非对称加密
- HTTP 中的 keep-alive 有了解吗?
- HTTP2 特性
- HTTP/2 对比 HTTP1.1
- HTTP/2 都有哪些特性?头部压缩的原理?
- HTTP/2 是怎么解决队头阻塞的
- HTTP/2 是如何压缩头部的
- HTTPS 握手
- 具体说一下 HTTP/2 中的多路复用
- GET 和 POST 的区别
- GET 就一定是幂等的吗?
- 状态码。302.304.301.401.403 的区别?
- 状态码。204 和 304 分别有什么作用?
- HTTP 和 HTTPS 握手差异?
- 为什么说 HTTPS 比 HTTP 安全呢
- 简单讲了一下非对称加密的握手过程
- 证书签名过程和如何防止被串改
- TCP/IP 网络分层模型是怎样分层的
- OSI 网络分层模型是怎样分层的
- TCP 和 UDP 区别
- HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2、HTTP/3 各版本之间的区别?
- [综合相关]
- CSRF 跨站请求伪造和 XSS 跨站脚本攻击是什么?
- 如果让你去实现一个 CSRF 攻击你会怎做?
- 如果使用 jsonp 的话会有什么安全问题吗?
- 你是如何解决跨域的?都有几种?
- 为什么说 GET 会留下历史记录?
- 从“在浏览器输入域名”到“页面静态资源完全加载”的整个流程
- 假设有两个子项目,他们需要共用同一个用户体系如何保证关掉页面之后打开另一个项目用户还是登录状态?
JS
- Promise 实现
- Generator 实现
- async、await 实现
- 垃圾回收中的堆和栈的区别
- 0.1 + 0.2 != 0.3 背后的原理?
- 手写 vue2/3 具体实现
- 手写继承
- requestAnimationFrame 属于宏任务还是微任务
- 动态表单实现
- null 为什么被 typeof 错误的判断为了'object'
- 洋葱模型
- 实现对象深拷贝
- 实现数组去重
- 实现一个 apply/call/bind 方法
- 实现一个函数,URL 参数解析为对象
- 实现一个 trim
- 实现柯理化函数
- 实现 loadsh 的 get 方法 (\_.get('a.b.c'))
- 查找字符串中的最长无重复子串
- 两个数组的并集与交集
- 排序算法实现
- 数组扁平化
Vue
- 双向绑定原理
- nextTick 原理
- nextTick 中的 waiting 是什么时候变为 true 的呢
- 虚拟 DOM
- Object.defineProperty()有什么缺点?Vue3 为什么用 Proxy
- Vue3 有哪些新的 API 或者有做哪些优化?
- 说一下 Vue 的 diff 算法
- diff 算法的缺点
Devops
- webpack 的构建流程、自定义 loader,插件原理、HMR 的实现、打包原理,常用的插件以及性能优化
- 单元测试做过吗?你是怎么做的?
- 对 tree-shaking 的了解(虽然生产模式下默认开启,但是由于经过 babel 编译全部模块被封装成 IIFE IIFE 存在副作用无法被 tree-shaking 掉 需要配置 { module: false }和 sideEffects: false rollup 和 webpack 的 shaking 程度不同,以一个 Class 为例子)
- webpack-dev-server 原理和如何处理跨域
-
书单
- 《 网络是怎样连接的 》
- 《 图解 HTTP 》
- 《 图解 TCP/IP 》
- 《 极客时间- 透视 HTTP 协议 》
- 《 TCP/IP 详解(第一卷)》
- 《 浏览器原理 》
- 《 DevOps 实战笔记 》
- 《 Nginx 核心知识 100 讲 》
- 《 学习 Javascipt 数据结构与算法 》
- 《 JavaScript 版 数据结构与算法 》
- 《 极客时间- 数据结构与算法之美 》
- 《 极客时间- 算法面试通关 》
代码实现
- 手写节流防抖
/**
* 节流
* @param {Func} callback 需要节流的函数
* @param {Number} wait 等待毫秒数
* 执行一次后,一段时间内不再执行
*/
function throttle(func, wait) {
let timer = null;
return function (...args) {
if (timer === null) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, wait);
}
};
}
/**
* 防抖
* @param {Func} callback 需要防抖的函数
* @param {Number} wait 等待毫秒数
* 一段时间内,取最后一次执行
*/
function debounce(func, wait) {
let timer = null;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
- 圣杯与双飞翼布局
/** 圣杯 **/
<div class="wrapper1">
<div class="main">
<p>bilibili</p>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<style>
.wrapper1 {
padding: 0 60px 0 30px;
}
.wrapper1 .main {
float: left;
width: 100%;
height: 300px;
background: red;
}
.wrapper1 .left {
float: left;
width: 30px;
margin-left: -100%;
background: blue;
height: 100px;
position: relative;
right: 30px;
}
.wrapper1 .right {
float: left;
width: 60px;
margin-left: -60px;
background: yellow;
height: 200px;
position: relative;
left: 60px;
}
</style>
/** 双飞翼 **/
<div class="wrapper2">
<div class="container">
<div class="main">
<p>bilibili</p>
</div>
</div>
<div class="left"></div>
<div class="right"></div>
</div>
<style>
.wrapper2 {
min-width: 630px;
}
.wrapper2 .container {
float: left;
width: 100%;
}
.wrapper2 .container .main {
height: 300px;
background: red;
margin: 0 600px 0 30px;
}
.wrapper2 .left {
float: left;
width: 30px;
background: blue;
height: 100px;
margin-left: -100%;
}
.wrapper2 .right {
float: left;
width: 600px;
background: yellow;
height: 200px;
margin-left: -600px;
}
</style>
- 数组长度为 5 且元素的随机数在 2-32 间不重复的值
// 生成 [n,m] 的随机整数
const creatRandomNum = (min,max) => parseInt(Math.random()*(max-min+1)+min);
function arr5(arr=[]) {
if(arr.length >= 5){return arr};
arr = [...new Set([...arr, creatRandomNum(2,32)])];
return arr5(arr);
}
4.写一个获取当前 url 查询字符串中的参数的方法
const getUrlQuery = (url = location.href) => {
try {
return [...new URL(url).searchParams].reduce(
(pre, [key, value]) => Object.assign(pre, { [key]: value }),
{},
);
} catch {
throw new Error(`url格式不正确。url: ${url}`);
}
};
- html5 中的 form 怎么关闭自动完成?
// 在 input 标签中,可以设置 autocomplete="off" 来关闭自动填充。
<form action="demo_form.html" method="get" autocomplete="off">
First name:<input type="text" name="fname" /><br />
E-mail: <input type="email" name="email" /><br />
<input type="submit" />
</form>
1.script 同步下载,下载成功继续阻塞 DOM 的渲染,立即执行。
2. async异步下载,下载成功后阻塞 DOM 的渲染,立即执行。
3. defer异步加载,下载成功后等待文档加载,文档加载完成后执行。
4.async、defer这两个属性无法应用于内联script。
- 实现一个 call / apply / bind / new
// call
Function.prototype.call2 = function (target, ...args) {
target._func = this;
const ret = target._func(...args);
delete target._func;
return ret;
};
// apply
Function.prototype.apply2 = function (target, args=[]) {
target._func = this;
const ret = target._func(...args);
delete target._func;
return ret;
};
// bind
Function.prototype._bind = function (target, ...res) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const that = this;
const _func = function(...args) {
// 判断当前函数是直接访问还是通过new进行构造
return that.apply(this instanceof _func ? this : target, res.concat(args));
}
// 添加一层原型,防止修改_func.prototype时影响到this.prototype
_func.prototype = Object.create(this.prototype);
return _func;
}
// new
function _new(target, ...args) {
const obj = Object.create(target.prototype);
const ret = target.apply(obj, args);
return typeof ret === 'object' ? ret : obj;
}
8.Object.create 的模拟实现
Object.create = function(target) {
function _func () {};
_func.prototype = target;
return new _func();
}
- instanceof 模拟实现
function _instanceof(left, right) {
let proto = left.__proto__;
let prototype = right.prototype;
while (true) {
if (proto === null) return false;
if (proto === prototype) return true;
proto = proto.__proto__;
}
}
10.解释一个为什么 10.toFixed(10)会报错?
/**
在我们的直觉上,10.toFixed(10) 是把整数的 10 转为浮点数并且保留 10 位小数部分。
但实际上会出错,是因为 JS 的解释器对 . 操作符产生了歧义。
在 JS 中 . 可以表示小数和从对象中取值。在这个例子中, 由于 10 是整数,
所以在 10. 默认是小数点,因此会报错。
**/
// 解决的办法有下面几种:
(10).toFixed(10) 个人喜欢这种,看起来舒服一点
10..toFixed(10)
11.将 Object 与 Map 互转
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));// Map { foo: "bar", baz: 42 }
var obj2 = Object.fromEntries(map);// {foo: "bar", baz: 42}
12.寄生组合式继承
// 通过构造函数来继承实例属性,通过原型链的混成形式来继承原型方法
function clonePrototype(Super,Suber){
var prototype = Object.create(Super.prototype);
prototype.constructor = Suber;
Suber.prototype = prototype;
}
function Super(name){
this.name = name
this.like = ['sing','dance','rap','basketball']
}
Super.prototype.sayName=function(){
console.log(this.name)
}
function Suber(name,age){
Super.call(this,name) // 继承属性
this.age=age
}
clonePrototype(Super,Suber);
Suber.prototype.sayAge=function(){
console.log(this.age)
}
var sub1 = new Suber('sss',18);
console.log(sub1.name); // -> sss
sub1.sayName(); // -> sss
sub1.sayAge(); // -> 18
13.如何让 (a == 1 && a == 2 && a == 3) 的值为 true?
var a = {
valueOf: (function () {
let i = 1;
//闭包的特性之一:i 不会被回收
return function () {
return i++;
}
})()
}
console.log(a == 1 && a == 2 && a == 3); // true