first

没啥面试经验就比较惨了。。

一面

  1. 自我介绍
  2. 为什么学习前端
  3. 技术栈
  4. js数据类型…
  5. 数组和string的方法…
  6. Undefined 和 Null的区别
  7. 双等号和全等的区别
  8. js闭包
  9. 闭包的缺点
  10. cookie session local storage
  11. es6新特性
  12. trim方法(去除前后空格)
  13. 正则匹配空格
  14. js 防抖 节流…
  15. ajax的两种方法的区别
  16. HTML标签语义化
  17. CSS3新特性
  18. 响应式布局
  19. 移动设备网页适配
  20. rem和em
  21. 小程序生命周期
  22. 小程序更新机制?
  23. vue生命周期..
  24. 常用指令v-bind if show for
  25. v-if 和 v-show的区别
  26. 前端性能优化
  27. 雪碧图
  28. 实现:居中(惨兮兮的给自己挖坑)
  29. node
  30. 挖坑(不敢造火箭2333(
  • JS数据类型

    1. String
    2. Number
    3. Boolean
    4. Null
    5. Undefined
    6. Array
    7. Object
    8. Function
  • string和array的属性和方法

    • 属性

      • length
      • constructor
      • prototype
    • string方法

      • charAt()
      • concat()
      • indexOf()
      • lastindexOf()
      • match()
      • replace()
      • search()
      • split()
      • substr()
      • substring()
      • toLowerCase()
      • toString()
      • toUpperCase()
      • trim()
      • valueOf()
    • array方法

      • concat()
      • filter()
      • find()
      • findIndex()
      • forEach()
      • includes()
      • indexOf()
      • isArray()
      • join()
      • lastIndexOf()
      • map()
      • pop()
      • push()
      • reduce()
      • reserve()
      • shift()
      • slice()
      • some()
      • sort()
      • toString()
    • 性能优化

      • 减少请求数量
        • 合并文件
        • 合并图片(雪碧图 base64
        • 减少重定向
        • 使用缓存
      • 减少资源大小
        • 压缩
        • webp
        • gzip
      • 优化网络连接
        • cdn
        • DNS预解析
        • 持久链接(keep-alive)
        • 管道化连接
      • 优化资源加载
        • 资源加载位置(CSS JS引入的位置)
        • 资源加载时机(异步加载,模块化加载,资源预/懒加载)
      • 减少重绘回流
        • 样式设置(CSS选择器 表达式 尺寸高度)
        • 渲染层(减少重绘范围,硬件加速)
        • DOM优化
      • 更好的API
        • 选择器的使用
        • 图片可视区域懒加载IntersectionObserver
        • requestAnimationFrame
      • webpack优化
        • 动态导入和按需加载
        • 剔除无用代码
        • 长缓存优化
        • 公用代码内联
  • ES6新特性

    • const和let
      • 局部变量和静态变量
    • 模板字符串
    • 箭头函数
    • 函数的参数默认值
    • Spread / Rest 操作符
      • 迭代器里的...是Spread操作符
      • 函数传参的...是Rest操作符
    • 二进制和八进制字面量
      • 0o0O为八进制
      • 0b0B为二进制
    • 对象和数组解构
    • 对象超类(super)
    • for in/of
    • ES6中的类(class)
  • cookie session local Storage

二面

  • vue虚拟dom
  • 双向数据绑定
  • 小程序 登录
  • vue好用的特性
  • js里的基础数据类型和引用对象分别在内存中的什么位置?
  • 内存里的 堆和栈
  • 排序算法
  • vue diff算法
  • 内存的深拷贝和浅拷贝
  • node
  • 工作室的团队(开始闲聊 项目分工

开始补课

  • js里的基础数据类型和引用对象分别在内存中的什么位置?

    • 基础数据类型存在栈内存里,按值访问;
    • 对象类型的变量标识符和指向堆内存中该对象的指针保存在栈内存,对象的内容保存在堆内存中,按引用访问
    • 拓展
      • 基础数据类型六种:undefined,null,string,number,boolean,symbol(new in es6)
        • 基础数据类型的值不可变
        • 比较是按值比较
          • ===== 的区别:== 只比较值,如果类型不同会进行隐式转换,=== 进行值和类型的比较
      • 引用数据类型:object,array,date,regexp,function
        • 引用类型的值是可变的
        • 引用类型的比较是引用的比较
        • 引用类型的值是保存在堆内存中的对象
        • js不能直接操作对象的内存空间(堆内存)
      • 检测类型的方法
        • typeof
        • instanceof
  • vue的virtual DOM

    • 虚拟 DOM,映射真实 DOM 的一个 JavaScript 对象,改变每个元素的状态,会先在 virtual DOM 上进行改变,而不是改变真正的 DOM。当有变化发生时,一个新的 virtual DOM 对象会被创建并计算新旧 virtual DOM 之间的差别,之后会将改变的部分渲染应用在真实的 DOM 上。
    • 与 react 不同的是 vue 在每次渲染的时候只计算了新旧 virtual DOM 之间差异的部分,不需要渲染整个组件树,而 react 则会将全部子组件重新渲染。
  • diff算法

    • 目的是为了将虚拟 DOM 进行比较的一个算法,更新节点的时候,遍历两个虚拟 DOM 中不同的部分,之后将其不同的部分进行渲染,生成新的 DOM。
  • vue 双向绑定原理

    • vue 通过数据劫持加发布订阅相结合方式实现双向绑定
    • 数据劫持主要通过 Object.defineProperty 来实现
    • emmmm具体看最后的链接 这里现在看不懂 因为没写过
  • 直接看博客吧 关于内存并不了解。。。

reference

JavaScript 深入了解基本类型和引用类型的值
Vue与React两个框架的区别和优势对比
解析vue2.0的diff算法
Vue双向绑定原理

border-formatting-context

看到一个好玩的,这个东西叫bfc(border-formatting-context),块级格式化上下文。

FC是formatting context的首字母缩写,直译过来是格式化上下文,它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素如何布局,以及和其他元素之间的关系和作用。
常见的FC有BFC、IFC(行级格式化上下文),还有GFC(网格布局格式化上下文)和FFC(自适应格式化上下文).
Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。元素的类型和 display 属性,决定了这个 Box 的类型。 不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。

触发条件

  1. float的值不能为none
  2. overflow的值不能为visible
  3. display的值为table-cell, table-caption, inline-block中的任何一个
  4. position的值不为relative和static 

BFC的约束规则

  1. 内部的Box会在垂直方向上一个接一个的放置
  2. 垂直方向的距离有margin决定(属于同一个BFC的两个相邻Box的margin会发生重叠,与方向无关)
  3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此
  4. BFC的区域不会与float的元素区域重叠
  5. 计算BFC的高度时,浮动子元素也参与计算
  6. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

作用

  1. 不和浮动元素重叠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
body {
width: 300px;
position: relative;
}

.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}

.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>

这样的布局会产生覆盖,aside会覆盖在main的左上角。原因是两个div box都在同一个bfc中,而main不具备bfc,因为:

每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。BFC的区域不会与float box重叠

所以main会与所处的bfc左边相接触。可以通过触发main生成bfc来实现自适应两栏布局。

1
2
3
.main {
overflow: hidden;
}

这样触发main的bfc之后,新的box不会和浮动的aside重叠。宽度会根据body和aside的宽度自适应宽度。

  1. 清除内部浮动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}

.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>

计算bfc高度时,浮动元素也会参与计算

为了达到内部清除浮动,可以触发par生成bfc,这样par的高度会计算内部元素的高度。

1
2
3
.par{
overflow:hidden
}
  1. 防止垂直margin重叠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>

此时两个p的margin会发生重叠,两个box之间的间隔只有一个100px

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠

可以在p外边再包一层容器,生成一个bfc,两个p不处于同一个bfc,就不会重叠margin值了。

创建块格式化上下文(MDN)

下列方式会创建块格式化上下文

  • 根元素(<html>)
  • 浮动元素(元素的 float 不是 none
  • 绝对定位元素(元素的 positionabsolutefixed
  • 行内块元素(元素的 displayinline-block
  • 表格单元格(元素的 displaytable-cell,HTML表格单元格默认为该值)
  • 表格标题(元素的 displaytable-caption,HTML表格标题默认为该值)
  • 匿名表格单元格元素(元素的 displaytable、``table-rowtable-row-group、``table-header-group、``table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table
  • overflow 值不为 visible 的块元素
  • display 值为 [flow-root](https://drafts.csswg.org/css-display/#valdef-display-flow-root) 的元素
  • contain 值为 layoutcontent或 paint 的元素
  • 弹性元素(displayflexinline-flex元素的直接子元素)
  • 网格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-countcolumn-width 不为 auto,包括 ``column-count1
  • column-spanall 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更Chrome bug)。

reference

什么是BFC?

关于CSS-BFC深入理解

块格式化上下文MDN

http和htttps的区别

带s的安全

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

基本概念

  • HTTP 采用标准tcp连接
  • HTTPS 在http下加入ssl层
    • 建立信息安全信道来传输
    • 确认网站的真实性

主要区别

  • HTTP未加密
  • HTTPS协议需要到ca申请证书,需要一定费用(好像有免费的可以用
  • 不带s不加密信息,带s对信息进行加密传输
  • HTTP端口是80,HTTPS端口为443
  • HTTP链接简单,无状态;HTTPS需要加密并进行身份验证。

reference

详细解析 HTTP 与 HTTPS 的区别

network-osi

计算机网络概述

体系结构

osi体系结构

  1. 应用层
  2. 表示层
  3. 会话层
  4. 传输层
  5. 网络层
  6. 数据链路层
  7. 物理层

TCP/IP体系结构

  1. 应用层(Telnet,FTP,SMTP)
  2. 传输层(TCP/UDP)
  3. 网络层(IP)
  4. 网络接口层

五层协议的体系结构

  1. 应用层
  2. 传输层
  3. 网络层
  4. 数据链路层
  5. 物理层

五层结构相比于七层的osi结构,将应用 表示 会话层统一为应用层。

应用层

通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。

常见通信协议:域名DNS,HTTP协议,邮件的POP3/SMTP协议

应用层交互的数据单元称为 报文

传输层

负责向两台主机进程之间的通信提供通用的数据传输服务。

常见协议:

  1. TCP(传输控制协议 Transmission Control Protocol)提供面向连接 可靠的数据传输。
    1. 面向连接
    2. 一对一连接,两个端点
    3. 可靠交付,TCP传输的数据无差错、不丢失、不重复、按序列到达
    4. 全双工通信。双方可以在任意时间发送数据,两端设有发送和接受缓存。
    5. 面向字节流。
  2. UDP(用户数据协议 User Datagram Protocol)提供无连接,尽最大努力的数据传输服务,不保证数据传输的可靠性。
    1. 无连接
    2. 尽最大努力交付。不保证可靠
    3. 面向报文
    4. 没有拥塞控制,网络出现阻塞不会影响主机发送,典型应用场景:直播,视频会议等
    5. 支持一对一,一对多,多对一,多对多
    6. 首部开销小,只有8字节(tcp首部20字节)

建立连接的过程在浏览器输入url发生了什么这篇里有介绍

网络层

为分组交换网上的不同主机提供通信服务。

在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报 ,简称 数据报。

就是说 tcp的数据会被IP协议打包成 IP数据报。

网络层的另一个任务 选择合适的路由:使源数据能通过该层的路由器找到目标主机。

常见设备:路由器,防火墙

数据链路层

在两个相邻节点之间传送数据时,数据链路层将网络层交下来的 IP 数据报组装程帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。

常见设备:网卡,网桥,交换机

物理层

实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。

常见设备:中继器,网线,调制调节器,光纤,同轴电缆。。

reference

计算机网络

计算机网络各层协议

design-pattern

设计模式目录

创建型

  1. Factory Method(工厂方法)
  2. Abstract Factory(抽象工厂)
  3. Builder(建造者)
  4. Prototype(原型)
  5. Singleton(单例)

结构型

  1. Adapter Class/Object(适配器)
  2. Bridge(桥接)
  3. Composite(组合)
  4. Decorator(装饰)
  5. Facade(外观)
  6. Flyweight(享元)
  7. Proxy(代理)

行为型

  1. Interpreter(解释器)
  2. Template Method(模板方法)
  3. Chain of Responsibility(责任链)
  4. Command(命令)
  5. Iterator(迭代器)
  6. Mediator(中介者)
  7. Memento(备忘录)
  8. Observer(观察者)
  9. State(状态)
  10. Strategy(策略)
  11. Visitor(访问者)

设计模式简介

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

什么是 GOF(四人帮,全拼 Gang of Four)

在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。

四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出的设计模式主要是基于以下的面向对象设计原则。

对接口编程而不是对实现编程。
优先使用对象组合而不是继承。

~ 这个坑有点大,晚点再进去,很多已经熟悉的用法可能已经用了设计模式中的某些方法,只是没有主要到而已 ~

reference

20 年前 GoF 提出的设计模式,对这个时代是否还有指导意义?

GOF 23种设计模式

设计模式-菜鸟教程

vue填坑-引用静态资源

vue-cli静态资源

静态资源可以通过两种方式进行处理:

  • 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。

  • 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。

从相对路径导入

当你在 JavaScript、CSS 或 *.vue 文件中使用相对路径 (必须以 . 开头) 引用一个静态资源时,该资源将会被包含进入 webpack 的依赖图中。在其编译过程中,所有诸如 <img src="...">background: url(...)CSS @import 的资源 URL 都会被解析为一个模块依赖。

就是说 相对路径引用 会被webpack打包

例如:

1
<img src="./image.png">

会被编译为:

1
h('img', { attrs: { src: require('./image.png') }})

在其内部,Vue CLI 通过 file-loader 用版本哈希值和正确的公共基础路径来决定最终的文件路径,再用 url-loader 将小于 4kb 的资源内联,以减少 HTTP 请求的数量。

可以通过 chainWebpack 调整内联文件的大小限制。例如,下列代码会将其限制设置为 10kb:

1
2
3
4
5
6
7
8
9
10
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
}
}

URL 转换规则

如果 URL 是一个绝对路径 (例如 /images/foo.png),它将会被保留不变。

如果 URL 以 . 开头,它会作为一个相对模块请求被解释且基于你的文件系统中的目录结构进行解析。

如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析。这意味着你甚至可以引用 Node 模块中的资源:

1
<img src="~some-npm-package/foo.png">

如果 URL 以 @ 开头,它也会作为一个模块请求被解析。它的用处在于 Vue CLI 默认会设置一个指向 <projectRoot>/src 的别名 @。(仅作用于模版中)

public 文件夹

VUE CLI 推荐将静态资源作为模块引入,会被webpack打包:

  • 脚本和样式表会被打包在一起,减少网络请求
  • 编译时查找文件,而不是在用户端报错
  • 打包后的文件名包含了内容哈希,浏览器不会加载缓存的老版本

文件名直接带内容哈希,6666…

使用public内的资源

public 目录提供的是一个应急手段,当你通过绝对路径引用它时,留意应用将会部署到哪里。如果你的应用没有部署在域名的根部,那么你需要为你的 URL 配置 publicPath 前缀:

在 public/index.html 或其它通过 html-webpack-plugin 用作模板的 HTML 文件中,你需要通过 <%= BASE_URL %> 设置链接前缀:

1
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

在模板中,你首先需要向你的组件传入基础 URL:

1
2
3
4
5
data () {
return {
publicPath: process.env.BASE_URL
}
}

然后:

1
<img :src="`${publicPath}my-image.png`">

何时使用 public 文件夹

  • 你需要在构建输出中指定一个文件的名字。
  • 你有上千个图片,需要动态引用它们的路径。
  • 有些库可能和 webpack 不兼容,这时你除了将其用一个独立的 <script> 标签引入没有别的选择。

reference

处理静态资源

设计模式-singleton-js

前言

张肖飞在暑假放假前给我说:“你要好好准备面试了,比如我之前面试的时候面试官问我什么是单例模式,那你面试前端肯定也会问你js里的单例模式。”

我:“啥是单例模式???”

单例模式

定义

单例对象的类必须保证只有一个实例存在,提供一个全局访问点。

解决的问题

一个全局使用的类频繁的创建与销毁。

何时使用

想控制实例数目,节省系统资源的时候。

如何解决

判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

应用场景

线程池,全局缓存等。 window 对象就是一个单例。这种只需要一个对象的就用单例模式。

简单实现(js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var Singleton = function(name){
this.name = name;
};

Singleton.prototype.getName = function(){
return this.name;
}

// 获取实例对象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {
instance = new Singleton(name);
}
return instance;
}
})();

// 测试单例模式的实例
var a = getInstance("aa");
var b = getInstance("bb");
console.log(b.getName()); // "aa"
console.log(a === b); // true

封装一个获取实例的模块

1
2
3
4
5
6
7
// 获取实例的封装代码
var getInstance = function(fn) {
var result;
return function(){
return result || (result = fn.call(this,arguments));
}
};

ES5实现,封装一个函数,作为一个对象返回,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function StorageSingleton () {}
StorageSingleton.prototype.getItem = function (key){
return localStorage.getItem(key)
}
StorageSingleton.prototype.setItem = function (key, value) {
return localStorage.setItem(key, value)
}

var Storage = (function(){
var instance
return function(){
return instance || instance = new StorageSingleton()
}
})()
var a = new Storage()
var b = new Storage()
a === b // true
a.setItem('a','a')
b.getItem('a') // 'a'

ES6原生加入了class的语法糖,这样的写法和其他语言的类构造方法相似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Storage {
constructor(){
if(!Storage.instance){
Storage.instance = this
}
return Storage.instance
}
getItem (key) {
return localStorage.getItem(key)
}
setItem (key, value) {
return localStorage.setItem(key, value)
}
}
let a = new Storage()
let b = new Storage()
a === b // true
a.setItem('a','a')
b.getItem('a') // 'a'

reference

JS单例模式实现ES5/ES6

单例模式

jS设计模式二:单例模式

浏览器输入URL后发生了什么

摘要

  1. DNS域名解析
  2. 建立TCP连接
  3. 发送HTTP请求
  4. 处理器处理请求
  5. 返回响应结果
  6. 关闭TCP连接
  7. 浏览器解析HTML
  8. 浏览器渲染布局

客户端检查

第一步不是解析地址,而是输入地址,并且要看你输入的地址是否合法。。

DNS域名解析

第一步解析URL所对应的的ip地址,如果本地(一般是DNS cache,hosts文件内的对应关系)有,则建立连接;如果没有,去dns服务器找。

客户端向本地dns服务器发送请求www.baidu.com

本地DNS服务器迭代查询过程

  • → 本地dns服务器先去根dns服务器查找,得到comDNS服务器ip地址返回给本地DNS服务器
  • → 本地DNS服务器再去comDNS服务器查询,comDNS服务器去查询www.baidu.com的相关DNS服务器的IP地址并返回给本地DNS服务器。
  • → 本地DNS将获取到的IP地址返回给客户端。

客户端到本地DNS服务器是递归查询,本地DNS服务器查询过程属于迭代查询。

一般情况下,本地DNS服务器缓存了部分DNS服务器地址,可以直接返回结果。

如果请求的资源是静态资源,有可能会到达cdn服务器;如果请求的是动态资源,流量可能会经过代理/网关,web服务器,应用服务器,数据库。对于大型应用来说,一般还会有负载均衡处理,由集群处理请求,集群之间通过实现会话同步、健康检查等机制来保证高可用。

后台服务器的部署架构又是另一方向的问题了。

建立连接

客户端获取到服务器ip地址后,就要建立连接。整个过程可以分解为建立连接、发送 HTTP 请求、返回 HTTP 响应、维持连接、释放连接五个部分

TCP三次握手

  1. 客户端发送带有SYN标志的数据包给服务端
  2. 服务端收到后,返回一个带有SYN/ACK标志的数据包,以示传达确认信息
  3. 客户端收到确认信息后再回传一个带ACK标志的数据包,握手结束。

连接成功

发送HTTP请求

https建立的连接会进行信息加密,一般是用TLS,加密后的信息再由TCP传输。

请求报文

报文首部
请求行
请求首部字段
通用首部字段
实体首部字段
其他
  • 请求行包括请求方法,URL,HTTP版本。
  • 首部字段传递重要信息,包括请求首部字段、通用首部字和实体首部字段。

服务器处理请求

服务器端收到请求后,由web服务器(http服务器)处理请求,后端如apache,ngnix,iis等服务处理。解析用户请求后,将资源文件处理后返回给浏览器客户端。如果有动态资源的话,还需要通过数据库调度返回信息。

返回响应结果

|响应报文|
|—|—|
|报文首部|
|空行|
|报文主体|

报文首部
状态行
响应首部字段
通用首部字段
实体首部字段
其他

HTTP状态码类别

响应结果中会有一个HTTP状态码
||类别|原因|
|—|—|—|
|1xx|信息性状态码|接收的请求正在处理|
|2xx|成功状态码|请求正常处理完毕|
|3xx|重定向状态码|需要进行附加操作以完成请求|
|4xx|客户端错误状态码|服务器无法处理请求|
|5xx|服务器错误状态码|服务器处理请求出错|

维持连接

完成一次 HTTP 请求后,服务器并不是马上断开与客户端的连接。在 HTTP/1.1 中,Connection: keep-alive 是默认启用的,表示持久连接,以便处理不久后到来的新请求,无需重新建立连接而增加慢启动开销,提高网络的吞吐能力。在反向代理软件 Nginx 中,持久连接超时时间默认值为 75 秒,如果 75 秒内没有新到达的请求,则断开与客户端的连接。同时,浏览器每隔 45 秒会向服务器发送 TCP keep-alive 探测包,来判断 TCP 连接状况,如果没有收到 ACK 应答,则主动断开与服务器的连接。注意,HTTP keep-alive 和 TCP keep-alive 虽然都是一种保活机制,但是它们完全不相同,一个作用于应用层,一个作用于传输层。

关闭TCP连接

为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次握手。

  1. 客户端发送FIN(m)
  2. 服务端收到后发送ACK(m+1)
  3. 服务端再次发送FIN(n)
  4. 客户端收到后回复ACK(n+1)

浏览器解析HTML

一般来说,浏览器解析网址之后获取到的都是一个HTML网页,当然也不止只有一个HTML,还有CSS JS,图片视频等资源。
浏览器获取到HTML之后,开始构建DOM数,解析CSS之后,生成CSS规则树,然后通过DOM树和CSS规则树生成渲染树。渲染树种没有headdisplay:none;之类的元素节点.

解析过程中遇到css可以继续解析HTML,但是在解析到JS后悔停止解析HTML,出现阻塞。

浏览器布局渲染

根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:replaint和reflow。

  • replaint:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。
  • reflow: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。

浏览器渲染引擎会先渲染不涉及尺寸和位置的replaint,之后在渲染需要涉及计算的尺寸位置的reflow。

reference

细说浏览器输入URL后发生了什么

浏览器输入 URL 后发生了什么?

在浏览器地址栏输入一个URL后回车,背后会进行哪些技术步骤? - 车小胖的回答 - 知乎

whta-happens-when

SSL/TLS协议运行机制的概述

博客再次复活

这下不仅仅是icestains.github.io可以用了, icestains.top也同样复活上线,暂时不想搞域名备案,先用CNAME的方式解析到github上,国内的阿里云服务器上的博客也同样可以使用了,除了同步更新可能有些麻烦之外,其他问题不大。

需要注意的还有图床问题,不能一直用github的仓库当图床,加载慢不说,添加图片是真的麻烦,想想图床问题怎么解决,阿里云服务那边的博客也能解决博客内加载图片的问题了。

重拾算法

最近一些事比较打击信心,所以需要充实一下。。好多东西忘记了的话,再看一遍,重新整理一遍。


最大公约数

输入两个数,输出这两个数的最大公约数

例:
input:  319,377
output: 29

实现思路:辗转相除法

若 r 是 a ÷ b 的余数,且r不为0, 则
gcd(a,b) = gcd(b,r)

python实现

1
2
3
4
5
6
7
8
9
10
11
12
13
def gcd(a, b):
if a < b:
tmp = a
a = b
b = tmp
while(b != 0):
r = a % b
a = b
b = r
return a


print(gcd(319, 377))

输出

python GCD.py
29