前端面经 - 看这篇就够了(笔者靠这个拿到阿里和字节的offer)(3)

自学几个月前端,为什么感觉什么都没学到??


这种现象在很多的初学者和自学前端的同学中是比较的常见的。

因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。

最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。

很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。

这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。

但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。

所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。

  • cubic-bezier函数:自定义速度模式,最后那个cubic-bezier,可以使用工具网站[7]来定制。

/* 变化在1s过渡 */

transition: 1s;

/* 指定过渡属性 */

transition: 1s height;

/* 指定多个属性同时发生过渡 */

transition: 1s height, 1s width;

/* 指定delay延时时间 */

transition: 1s height, 1s 1s width;

/* 指定状态变化速度 */

transition: 1s height ease;

/* 指定自定义移状态变化速度 */

transition: 1s height cubic-bezier(.83,.97,.05,1.44);

transition的局限 transition的优点在于简单易用,但是它有几个很大的局限。

  1. transition需要事件触发,所以没法在网页加载时自动发生。

  2. transition是一次性的,不能重复发生,除非一再触发。

  3. transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。

  4. 一条transition规则,只能定义一个属性的变化,不能涉及多个属性。

CSS Animation就是为了解决这些问题而提出的。

  • Transition 强调过渡,Transition + Transform = 两个关键帧的Animation

  • Animation 强调流程与控制,Duration + TransformLib + Control = 多个关键帧的Animation

2. animation动画

.element:hover {

animation: 1s rainbow;

/*

animation: 1s rainbow infinite; 关键字infinite让动画无限次播放

animation: 1s rainbow 3; 指定动画播放次数

*/

}

@keyframes rainbow {

0% { background: #c00; }

50% { background: orange; }

100% { background: yellowgreen; }

}

其中animation的值是简写,扩展开依次是:

  1. animation-name: 指定一个 @keyframes 的名称,动画将要使用这个@keyframes定义。

  2. animation-duration: 整个动画需要的时长。

  3. animation-timing-function: 动画进行中的时速控制,比如 ease 或 linear.

  4. animation-delay: 动画延迟时间。

  5. animation-direction: 动画重复执行时运动的方向。

  6. animation-iteration-count: 动画循环执行的次数。

  7. animation-fill-mode: 设置动画执行完成后/开始执行前的状态,比如,你可以让动画执行完成后停留在最后一幕,或恢复到初始状态。

  8. animation-play-state: 暂停/启动动画。

  • 参考:CSS动画简介[8]

10. CSS优化、提高性能的方法有哪些

  • 多个css合并,尽量减少HTTP请求

  • 将css文件放在页面最上面

  • 移除空的css规则

  • 避免使用CSS表达式

  • 选择器优化嵌套,尽量避免层级过深

  • 充分利用css继承属性,减少代码量

  • 抽象提取公共样式,减少代码量

  • 属性值为0时,不加单位

  • 属性值为小于1的小数时,省略小数点前面的0

  • css雪碧图

四、javascript


  • 参考:javascript面试题整理[9]

五、vue


  • 参考:vue面试题整理[10]

六、webpack


  • webpack 是一个模块打包工具,你可以使用webpack管理你的模块依赖,并编绎输出模块们所需的静态文件。

  • 它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。

  • 对于不同类型的资源,webpack有对应的模块加载器loader

  • webpack模块打包器会分析模块间的依赖关系,最后生成优化且合并后的静态资源。

  • 插件功能提供了处理各种文件过程中的各个生命周期钩子,使开发者能够利用插件功能开发很多自定义的功能。

1. 我写过的webpack相关的文章

  • webpack打包原理\&手写webpack核心打包过程[11]

  • 在webpack-dev-server中添加mock中间件实现前端模拟数据功能[12]

  • webpack常用配置详解[13]

  • webpack配置优化[14]

2. 核心打包原理简述

3. Loader

编写一个loader:

loader就是一个node模块,它输出了一个函数。当某种资源需要用这个loader转换时,这个函数会被调用。并且,这个函数可以通过提供给它的this上下文访问Loader API。 reverse-txt-loader

解析顺序从下向上,从右向左

// 定义

module.exports = function(src) {

//src是原文件内容(abcde),下面对内容进行处理,这里是反转

var result = src.split(‘’).reverse().join(‘’);

//返回JavaScript源码,必须是String或者Buffer

return module.exports = '${result}';

}

//使用

{

test: /.txt$/,

loader: ‘reverse-txt-loader’

}

4. 配置举例

§ base

module.exports = {

entry: {

app: ‘./src/main.js’

},

output: {

path: path.resolve(__dirname, ‘…/dist’),

filename: ‘[name].js’,

publicPath: ‘’

},

resolve: {

extensions: [‘.js’, ‘.vue’, ‘.json’, ‘.css’, ‘.less’],

alias: {

‘@’: resolve(‘src’),

src: resolve(‘src’),

static: resolve(‘static’)

}

},

module: {

rules: [

{

test: /.vue$/,

loader: ‘vue-loader’,

options: vueLoaderConfig

},

{

test: /.js$/,

loader: ‘babel-loader’,

include: [resolve(‘src’), resolve(‘test’)]

},

{

test: /.(png|jpe?g|gif|svg)(?.*)?$/,

loader: ‘url-loader’,

query: {

limit: 1,

name: utils.assetsPath(img/[name].[ext])

},

include: /nobase64/

},

{

test: /.svg(?\S*)?$/,

loader: ‘svg-sprite-loader’,

query: {

prefixize: true,

name: ‘[name]-[hash]’

},

include: [resolve(‘src’)],

exclude: /node_modules|bower_components/

}

]

},

plugins: [

new VueLoaderPlugin(),

new ProgressBarPlugin({

format: ‘build [:bar] ’ + chalk.green.bold(’:percent’) + ’ (:elapsed seconds) : (:msg)',

clear: false,

width: 60

})

]

};

§ dev

var path = require(‘path’);

var utils = require(‘./utils’);

var webpack = require(‘webpack’);

var config = require(‘…/config’);

var merge = require(‘webpack-merge’);

var baseWebpackConfig = require(‘./webpack.base.conf’);

var CopyWebpackPlugin = require(‘copy-webpack-plugin’);

var MyPlugin = require(‘./htmlPlugin’);

var HtmlWebpackPlugin = require(‘html-webpack-plugin’);

var MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);

var OptimizeCSSPlugin = require(‘optimize-css-assets-webpack-plugin’);

const TerserPlugin = require(‘terser-webpack-plugin’);

module.exports = merge(baseWebpackConfig, {

mode: ‘development’,

externals: {

vue: ‘Vue’

},

devtool: ‘#source-map’,

output: {

path: config.build.assetsRoot,

filename: utils.assetsPath(js/[name].js),

chunkFilename: utils.assetsPath(js/[name].js)

},

plugins: [

new webpack.HotModuleReplacementPlugin(),

new FriendlyErrorsPlugin(),

new CopyWebpackPlugin([

{

from: path.resolve(__dirname, ../static),

to: path.resolve(config.dev.assetsPublicPath, /dist/static)

}

]),

new HtmlWebpackPlugin({

alwaysWriteToDisk: true,

filename: ‘index.html’,

template: path.resolve(__dirname, ../src/index.html), // 模板路径

inject: false,

excludeChunks: [],

baseUrl: ‘’,

currentEnv: ‘development’,

envName: ‘local’,

curentBranch: ‘’

}),

new HtmlHardDisk()

],

optimization: {

/*

作用域提升插件

[注意] 这个插件在 mode: production 时时默认开启的

这样配置时为了在 development 时也开启

https://webpack.js.org/configuration/optimization/#optimizationconcatenatemodules

*/

concatenateModules: true,

splitChunks: {

cacheGroups: {

commons: {

test: /[\/]node_modules[\/]/,

name: ‘vendors’,

chunks: ‘all’

},

styles: {

name: ‘styles’,

test: /.css$/,

chunks: ‘all’,

enforce: true

}

}

},

runtimeChunk: {

name: ‘manifest’

},

minimizer: [

// 代码压缩UglifyJsPlugin的升级版

new TerserPlugin({

cache: true,

parallel: true,

terserOptions: {

sourceMap: true,

warnings: false,

compress: {

// warnings: false

},

ecma: 6,

mangle: true

},

sourceMap: true

}),

new OptimizeCSSPlugin({

cssProcessorOptions: {

autoprefixer: {

browsers: ‘last 2 version, IE > 8’

}

}

})

]

}

}

§ prod

var path = require(‘path’);

var utils = require(‘./utils’);

var webpack = require(‘webpack’);

var merge = require(‘webpack-merge’);

var baseWebpackConfig = require(‘./webpack.base.conf’);

var HtmlWebpackPlugin = require(‘html-webpack-plugin’);

var FriendlyErrorsPlugin = require(‘friendly-errors-webpack-plugin’);

var CopyWebpackPlugin = require(‘copy-webpack-plugin’);

var HtmlHardDisk = require(‘html-webpack-harddisk-plugin’);

var MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);

var OptimizeCSSPlugin = require(‘optimize-css-assets-webpack-plugin’);

const TerserPlugin = require(‘terser-webpack-plugin’);

module.exports = merge(baseWebpackConfig, {

mode: ‘production’,

externals: {

vue: ‘Vue’

},

output: {

path: config.build.assetsRoot,

filename: utils.assetsPath(js/[name].js),

chunkFilename: utils.assetsPath(js/[name]-[chunkhash].js)

},

plugins: [

// http://vuejs.github.io/vue-loader/en/workflow/production.html

new webpack.DefinePlugin({

‘process.env’: env

}),

// extract css into its own file

new MiniCssExtractPlugin({

filename: utils.assetsPath(‘css/[name].css’),

allChunks: true

}),

// copy custom static assets

new CopyWebpackPlugin([

{

from: path.resolve(__dirname, ../static),

to: path.resolve(__dirname, ../dist/static)

}

]),

new HtmlWebpackPlugin({

alwaysWriteToDisk: true,

filename: ‘index.html’,

template: path.resolve(__dirname, ../src/index.html), // 模板路径

inject: false,

baseUrl: ‘’,

currentEnv: ‘production’,

envName: ‘prod’,

curentBranch: ‘’

}),

new BundleAnalyzerPlugin()

],

optimization: {

minimizer: [

// 代码压缩UglifyJsPlugin的升级版

new TerserPlugin({

//  cache: true,

parallel: true,

terserOptions: {

warnings: false,

compress: {

},

//  ecma: 6,

mangle: true

},

sourceMap: true

}),

new OptimizeCSSPlugin({

cssProcessorOptions: {

autoprefixer: {

browsers: ‘last 2 version, IE > 8’

}

}

})

],

splitChunks: {

cacheGroups: {

commons: {

test: /[\/]node_modules[\/]/,

name: ‘vendors’,

chunks: ‘all’

}

}

},

runtimeChunk: {

name: ‘manifest’

}

}

};

5. 手动chungk分包

  • optimization.splitChunks(4之前老版本用CommonsChunkPlugin)

  • vue路由懒加载[15]

6. 打包加速的方法

  • devtool 的 sourceMap较为耗时

  • 开发环境不做无意义的操作:代码压缩、目录内容清理、计算文件hash、提取CSS文件等

  • 第三方依赖外链script引入:vue、ui组件、JQuery等

  • HotModuleReplacementPlugin:热更新增量构建

  • DllPlugin& DllReferencePlugin:动态链接库,提高打包效率,仅打包一次第三方模块,每次构建只重新打包业务代码。

  • thread-loader,happypack:多线程编译,加快编译速度

  • noParse:不需要解析某些模块的依赖

  • babel-loader开启缓存cache

  • splitChunks(老版本用CommonsChunkPlugin):提取公共模块,将符合引用次数(minChunks)的模块打包到一起,利用浏览器缓存

  • Tree Shaking 摇树:基于ES6提供的模块系统对代码进行静态分析, 并在压缩阶段将代码中的死代码(dead code)移除,减少代码体积。

7. 打包体积 优化思路

  • webpack-bundle-analyzer插件可以可视化的查看webpack打包出来的各个文件体积大小,以便我们定位大文件,进行体积优化

  • 提取第三方库或通过引用外部文件的方式引入第三方库

  • 代码压缩插件UglifyJsPlugin

  • 服务器启用gzip压缩

  • 按需加载资源文件 require.ensure=

  • 剥离css文件,单独打包

  • 去除不必要插件,开发环境与生产环境用不同配置文件

  • SpritesmithPlugin雪碧图,将多个小图片打包成一张,用background-image,backgroud-pisition,width,height控制显示部分

  • url-loader 文件大小小于设置的尺寸变成base-64编码文本,大与尺寸由file-loader拷贝到目标目录

8. Tree Shaking 摇树

背景: 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。

思路: 基于ES6提供的模块系统对代码进行静态分析,并将代码中的死代码(dead code)移除的一种技术。因此,利用Tree Shaking技术可以很方便地实现我们代码上的优化,减少代码体积。

Tree Shaking 摇树 是借鉴了 rollup 的实现。

4b9491da7c7dd3a057f72adeae2aba7e.gif

摇树删除代码的原理: webpack基于ES6提供的模块系统,对代码的依赖树进行静态分析,把import & export标记为3类:

  • 所有import标记为/* harmony import */

  • 被使用过的export标记为/harmony export([type])/,其中[type]和webpack内部有关,可能是binding,immutable等;

  • 没有被使用的export标记为/* unused harmony export [FuncName] */,其中[FuncName]为export的方法名,之后使用Uglifyjs(或者其他类似的工具)进行代码精简,把没用的都删除。

为何基于es6模块实现(ES6 module 特点:):

  • 只能作为模块顶层的语句出现

  • import的模块名只能是字符串常量

  • import binding是immutable的

条件:

  1. 首先源码必须遵循 ES6 的模块规范 (import & export),如果是 CommonJS 规范 (require) 则无法使用。

  2. 编写的模块代码不能有副作用,如果在代码内部改变了外部的变量则不会被移除。

配置方法:

在package.json里添加一个属性:

{

// sideEffects如果设为false,webpack就会认为所有没用到的函数都是没副作用的,即删了也没关系。

“sideEffects”: false,

// 设置黑名单,用于防止误删代码

“sideEffects”: [

// 数组里列出黑名单,禁止shaking下列代码

“@babel/polly-fill”,

“*.less”,

// 其它有副作用的模块

“./src/some-side-effectful-file.js”

],

}

tree-shaking 摇掉代码中未使用的代码 在生产模式下自动开启

tree-shaking并不是webpack中的某一个配置选项,是一组功能搭配使用后的优化效果,会在生产模式下自动启动

// 在开发模式下,设置 usedExports: true ,打包时只会标记出哪些模块没有被使用,不会删除,因为可能会影响 source-map的标记位置的准确性。

{

mode: ‘develpoment’,

optimization: {

// 优化导出的模块

usedExports: true

},

}

// 在生产模式下默认开启 usedExports: true ,打包压缩时就会将没用到的代码移除

{

mode: ‘production’,

//  这个属性的作用就是集中配置webpack内部的优化功能

optimizition: {

// 只导出外部使用的模块成员 负责标记枯树叶

usedExports: true,

minimize: true, // 自动压缩代码 负责摇掉枯树叶

/**

* webpack打包默认会将一个模块单独打包到一个闭包中

* webpack3中新增的API 将所有模块都放在一个函数中 ,尽可能将所有模块合并在一起,

* 提升效率,减少体积  达到作用域提升的效果

*/

concatenateModules: true,

},

}

使用摇树的注意事项:

  1. 使用 ES6 模块语法编写代码

  2. 工具类函数尽量以单独的形式输出,不要集中成一个对象或者类

  3. 声明 sideEffects

  4. 自己在重构代码时也要注意副作用

tree-shaking & babel 使用babel-loader处理js代码会导致tree-shaking失效的原因:

  • treeshaking 使用的前提必须是ES module组织的代码,也就是说交给ESMOdule处理的代码必须是ESM。当我们使用babel-loader处理js代码之后就有可能将ESM 转换 成commonjs规范(preset-env插件工作的时候就会将esm => coommonjs)

解决办法:

收到配置preset-env的modules:false,确保不会开启自动转换的插件(在最新版本的babel-loader中自动帮我们关闭了转换成commonjs规范的功能)

presets: [

[‘@babel/preset-env’, {module: ‘commonjs’}]

]

9. 常用插件简述

  • webpack-dev-server

  • clean-webpack-plugin:编译前清理输出目录

  • CopyWebpackPlugin:复制文件

  • HotModuleReplacementPlugin:热更新

  • ProvidePlugin:全局变量设置

  • DefinePlugin:定义全局常量

  • splitChunks(老版本用CommonsChunkPlugin):提取公共模块,将符合引用次数的模块打包到一起

  • mini-css-extract-plugin(老版本用ExtractTextWebpackPlugin):css单独打包

  • TerserPlugin(老版本用UglifyJsPlugin):压缩代码

  • progress-bar-webpack-plugin:编译进度条

  • DllPlugin& DllReferencePlugin:提高打包效率,仅打包一次第三方模块

  • webpack-bundle-analyzer:可视化的查看webpack打包出来的各个文件体积大小

  • thread-loader,happypack:多进程编译,加快编译速度

nodejs


1. 我写的nodejs相关文章

  • koa+mongondb实现用户登录注册模块[16]

  • nodejs的fs模块回调函数风格的异步操作转化为promise和await风格[17]

2. nodejs常用模块

  • path

  • fs

  • http,url

  • express

  • koa

  • mongoose

  • process

  • cookie, session

  • crypto加密相关

  • os

3. koa 中间件思想,洋葱模型

class Middleware {

constructor() {

this.middlewares = [];

}

use(fn) {

if(typeof fn !== ‘function’) {

throw new Error('Middleware must be function, but get ’ + typeof fn);

}

this.middlewares.push(fn);

return this;

}

compose() {

const middlewares = this.middlewares;

return dispatch(0);

function dispatch(index) {

const middleware = middlewares[index];

if (!middleware) {return;}

try{

const ctx = {};

const result = middleware(ctx, dispatch.bind(null, index + 1));

return Promise.resolve(result);

} catch(err) {

return Promise.reject(err);

}

}

}

}

// 使用

const middleware = new Middleware();

middleware.use(async (ctx, next) => {

console.log(1);

await next();

console.log(2);

});

middleware.use(async (ctx, next) => {

console.log(3);

await next();

console.log(4);

});

middleware.compose();// 1 3 4 2

4. express和koa的区别

  1. 编码风格:express采用回调函数风格,koa1 采用 generator,koa2(默认)使用await,风格上更加优雅,koa与es6,7的结合更加紧密;

  2. 错误处理:express采用在回调中错误优先的处理方式,深层次的异常捕获不了,使得必须在每一层回调里面处理错误,koa的使用try catch捕获错误,将错误上传可以统一处理错误;

  3. Koa 把 Express 中内置的 router、view 等功能都移除了,使得框架本身更轻量;

  4. express社区较大,文档也相对较多,koa社区相对较小;

网络

1. 网络七层协议(OSI模型)

OSI是一个定义良好的协议规范集,并有许多可选部分完成类似的任务。它定义了开放系统的层次结构、层次之间的相互关系以及各层所包括的可能的任务,作为一个框架来协调和组织各层所提供的服务。

OSI参考模型并没有提供一个可以实现的方法,而是描述了一些概念,用来协调进程间通信标准的制定。即OSI参考模型并不是一个标准,而是一个在制定标准时所使用的概念性框架。

d3c0171f6448d38bc76287f31ed9a1a3.png

image.png

  • 第7层 应用层

应用层(Application Layer)提供为应用软件而设计的接口,以设置与另一应用软件之间的通信。例如:HTTP、HTTPS、FTP、Telnet、SSH、SMTP、POP3等。

  • 第6层 表示层

表示层(Presentation Layer)把数据转换为能与接收者的系统格式兼容并适合传输的格式。

  • 第5层 会话层

会话层(Session Layer)负责在数据传输中设置和维护计算机网络中两台计算机之间的通信连接。

  • 第4层 传输层

传输层(Transport Layer)把传输表头(TH)加至数据以形成数据包。传输表头包含了所使用的协议等发送信息。例如:传输控制协议(TCP)等。

  • 第3层 网络层

网络层(Network Layer)决定数据的路径选择和转寄,将网络表头(NH)加至数据包,以形成分组。网络表头包含了网络资料。例如:互联网协议(IP)等。

  • 第2层 数据链路层

数据链路层(Data Link Layer)负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成信息框(Data Frame)。数据链表头(DLH)是包含了物理地址和错误侦测及改错的方法。数据链表尾(DLT)是一串指示数据包末端的字符串。例如以太网、无线局域网(Wi-Fi)和通用分组无线服务(GPRS)等。

分为两个子层:逻辑链路控制(logical link control,LLC)子层和介质访问控制(Media access control,MAC)子层。

  • 第1层 物理层

物理层(Physical Layer)在局部局域网上发送数据帧(Data Frame),它负责管理电脑通信设备和网络媒体之间的互通。包括了针脚、电压、线缆规范、集线器、中继器、网卡、主机接口卡等。

2. TCP 协议三次握手

  • 客户端通过 SYN 报文段发送连接请求,确定服务端是否开启端口准备连接。状态设置为 SYN_SEND;

  • 服务器如果有开着的端口并且决定接受连接,就会返回一个 SYN+ACK 报文段给客户端,状态设置为 SYN_RECV

  • 客户端收到服务器的 SYN+ACK 报文段,向服务器发送 ACK 报文段表示确认。此时客户端和服务器都设置为 ESTABLISHED 状态。连接建立,可以开始数据传输了。

翻译成大白话就是: 客户端:你能接收到我的消息吗? 服务端:可以的,那你能接收到我的回复吗? 客户端:可以,那我们开始聊正事吧。

为什么是3次?:避免历史连接,确认客户端发来的请求是这次通信的人 为什么不是4次?:3次够了第四次浪费

3. TCP 协议四次挥手

09d35eb162fba1ad28511c9056603b4e.png

image.png

  1. 为什么不是两次?
  • 两次情况客户端说完结束就立马断开不再接收,无法确认服务端是否接收到断开消息,但且服务端可能还有消息未发送完。

为什么不是三次?

  • 3次情况服务端接收到断开消息,向客户端发送确认接受消息,客户端未给最后确认断开的回复。

http


1. HTTP 请求报文结构

首行是Request-Line包括:请求方法请求URI协议版本CRLF

首行之后是若干行请求头,包括general-headerrequest-header或者entity-header,每个一行以CRLF结束

请求头和消息实体之间有一个CRLF分隔

根据实际请求需要可能包含一个消息实体 一个请求报文例子如下:

GET /Protocols/rfc2616/rfc2616-sec5.html HTTP/1.1

Host: www.w3.org

Connection: keep-alive

Cache-Control: max-age=0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36

Referer: https://www.google.com.hk/

Accept-Encoding: gzip,deflate,sdch

Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

Cookie: authorstyle=yes

If-None-Match: “2cc8-3e3073913b100”

If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT

name=qiu&age=25

2. HTTP 响应报文结构

  • 首行是状态行包括:HTTP版本,状态码,状态描述,后面跟一个CRLF

  • 首行之后是若干行响应头,包括:通用头部,响应头部,实体头部

  • 响应头部和响应实体之间用一个CRLF空行分隔

  • 最后是一个可能的消息实体 响应报文例子如下:

HTTP/1.1 200 OK

Date: Tue, 08 Jul 2014 05:28:43 GMT

Server: Apache/2

Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT # 最后修改时间,用于协商缓存

ETag: “40d7-3e3073913b100” # 文件hash,用于协商缓存

Accept-Ranges: bytes

Content-Length: 16599

Cache-Control: max-age=21600 # 强缓存(浏览器端)最大过期时间

Expires: Tue, 08 Jul 2014 11:28:43 GMT # 强缓存(浏览器端)过期时间

P3P: policyref=“http://www.w3.org/2001/05/P3P/p3p.xml”

Content-Type: text/html; charset=iso-8859-1

{“name”: “qiu”, “age”: 25}

3. HTTP常见状态码及其含义

  • 1XX:信息状态码

  • 100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息

  • 2XX:成功状态码

  • 200 OK 正常返回信息

  • 201 Created 请求成功并且服务器创建了新的资源

  • 202 Accepted 服务器已接受请求,但尚未处理

  • 3XX:重定向

  • 301 Moved Permanently 请求的网页已永久移动到新位置。

  • 302 Found 临时性重定向。

  • 303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。

  • 304 Not Modified 自从上次请求后,请求的网页未修改过。

  • 4XX:客户端错误

  • 400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。

  • 401 Unauthorized 请求未授权。

  • 403 Forbidden 禁止访问。

  • 404 Not Found 找不到如何与 URI 相匹配的资源。

  • 5XX: 服务器错误

  • 500 Internal Server Error 最常见的服务器端错误。

  • 503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

4. 常见web安全及防护

  • 参考:常见web攻击及防护方法[18]

5. http1.0、http1.1、http2.0区别

§ http1.0 vs http1.1

  1. 长连接,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接,可有效减少TCP的三次握手开销;

  2. 缓存处理,增加了Cache-Control等缓存相关头(看下面详细介绍);

  3. 请求头增加Host,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

  4. 请求头增加range可用于断点续传,它支持只请求资源的某个部分,可用于断点续传

  5. 增加请求方法:(OPTIONS,PUT, DELETE, TRACE, CONNECT)

  6. 新增了24个状态码,(如100Continue,发请求体之前先用请求头试探一下服务器,再决定要不要发请求体

6. http1.x vs http2.0

  1. 服务端推送

  2. 多路复用,多个请求都在同一个TCP连接上完成

  3. 报文头部压缩,HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量

  • 参考:HTTP1.0、HTTP1.1 和 HTTP2.0 的区别[19]

7. Cache-Control

用于判断强缓存,也就是是否直接取在客户端缓存文件,不请求后端。

请求头和响应头都可以使用。

请求时的缓存指令包括:no-cache、no-store、max-age、max-stale、min-fresh、only-if- cached, 响应消息中的指令包括:public、private、no-cache、no-store、no-transform、must- revalidate、proxy-revalidate、max-age。

常用指令含义如下:

  • no-cache:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。

  • no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。

  • public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。

  • private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。

  • max-age:指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

8. https

HTTPS = HTTP + 加密 + 认证 + 完整性保护

http的不足

  • 通信使用未加密的明文,内容容易被窃取

  • 不验证通信方的身份,容易遭遇伪装

  • 无法验证报文的完整性,容易被篡改

https就是为了解决上述http协议的安全性问题诞生的。https并非是应用层的新协议,是基于http协议的,将http和tcp协议接口部分用SSLTLS协议代替而已。

http: IP ➜ TCP ➜ HTTP(应用层)

https: IP ➜ TCP ➜ SSL ➜ HTTP(应用层)

§ 加密

  • SSL(Secure Sockets Layer安全套接字层协议)

  • TLS(Transport Layer Security传输层安全协议)

对称加密:用同一个密钥加密、解密。常用对称加密算法:AES,RC4,3DES 非对称加密:用一个密钥加密的数据,必须使用另一个密钥才能解密。常用非对称加密算法:RSA,DSA/DSS

常用HASH算法:MD5,SHA1,SHA256

其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。

由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。

非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。

§ CA 证书包含的信息:

CA(Certification Authority证书颁发机构)

  • 公钥

  • 网站地址

  • 证书的颁发机构

  • 过期时间

§ https加密通信的流程:

  1. 浏览器输入url请求网站,并附带自己支持的一套加密规则。

  2. 网站制作证书,这个应该是网站建站的时候就已经弄好了。证书分为服务器证书和客户端证书,我们所说的证书一般都是指服务器证书(ssl证书详细解读[20])。制作过程如下:

  3. 制作CSR文件。就是制作Certificate Secure Request证书请求文件,制作过程中,系统会产生2个密钥,一个是公钥就是这个CSR文件,另一个是私钥,存在服务器上。

  4. CA认证。将CSR文件提交给CA,一般有两种认证方式:域名认证 和 企业文档认证。

  5. 证书安装。收到CA证书后,将证书部署在服务器上。

  6. 网站从浏览器发过来的加密规则中选一组自身也支持的加密算法和hash算法,并向浏览器发送带有公钥的证书,当然证书还包含了很多信息,如网站地址、证书的颁发机构、过期时间等。

  7. 浏览器解析证书。

  8. 验证证书的合法性。如颁发机构是否合法、证书中的网站地址是否与访问的地址一致,若不合法,则浏览器提示证书不受信任,若合法,浏览器会显示一个小锁头。

  9. 若合法,或用户接受了不合法的证书,浏览器会生成一串随机数的密码(即密钥),并用证书中提供的公钥加密。

  10. 使用约定好的hash计算握手消息,并使用生成的随机数(即密钥)对消息进行加密,最后将之前生成的所有消息一并发送给网站服务器。

  11. 网站服务器解析消息。用已有的私钥将密钥解密出来,然后用密钥解密发过来的握手消息,并验证是否跟浏览器传过来的一致。然后再用密钥加密一段握手消息,发送给浏览器。

  12. 浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。

下图表示https加密通信的过程:66610d86aef96c6eaae0f3a384a8037f.png

设计模式


  • 常用设计模式分类[21]

  • 单例模式(Singleton Pattern)[22]

  • 发布订阅模式(又叫观察者模式Observer Pattern)[23]

  • 中介者模式(Mediator Pattern)[24]

  • 策略模式(Strategy Pattern)[25]

  • 代理模式(Proxy Pattern)[26]

  • 迭代器模式(Iterator Pattern)[27]

  • 适配器模式(Adapter Pattern)[28]

  • 命令模式(Command Pattern)[29]

  • 组合模式(Composite Pattern)[30]

  • 模板方法模式(Template Method)[31]

  • 享元模式(Flyweight Pattern)[32]

  • 模职责链模式 (Chain of Responsibility Pattern)[33]

  • 状态模式\(State Pattern\)[34]

git 常用操作


  • 参考:Git常用操作指南[35]

| 命令 | 作用 |

| — | — |

| git status |

|

| git diff |

|

| git add |

|

| git commit |

|

| git push |

|

| git branch |

|

| git checkout |

|

| git pull/fetch | git pull = git fetch + git merge |

| git merge |

|

§ git rebase 作用:将一个分支的更改合并入另一个分支。

目的

  1. 让多个人在同一个分支开发的提交节点形成一条线,而不是多条线

  2. 让你提交的commit在该分支的最前面

使用场景

  1. 开发分支合并主分支的更新;

  2. 不能在主分支上使用rebase,因为会破坏历史记录

§ merge 和 rebase 的区别 git rebase和git merge做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。

  • git merge 将两个分支的提交记录按照顺序排序

  • git rebase 把被合并的旁分支的修改直接追加在主分支提交记录后面。

一些其他常见问题


  • 自我介绍

  • 你有什么爱好?

  • 你最大的优点和缺点是什么?

  • 你为什么会选择这个行业,职位?

  • 你觉得你适合从事这个岗位吗?

  • 你有什么职业规划?

  • 你对工资有什么要求?

  • 如何看待前端开发?

  • 未来三到五年的规划是怎样的?

  • 你的项目中技术难点是什么?遇到了什么问题?你是怎么解决的?

  • 你们部门的开发流程是怎样的

  • 你认为哪个项目做得最好?

  • 说下工作中你做过的一些性能优化处理?

  • 最近在看哪些前端方面的书?

  • 平时是如何学习前端开发的?

  • 你最有成就感的一件事?

  • 你为什么要离开前一家公司?

  • 你对加班的看法?

  • 你希望通过这份工作获得什么?

  • 面试完你还有什么问题要问的吗?

待整理


  1. vuex:
  • 用法

  • 使用场景

  • 解决了什么问题

  • Vuex面试题汇总[36]

typescript:【ok】

  • 使用场景

  • 范型

  • 类型检查

  • 接口和类型别名的区别

  • 与vue2和3搭配使用的姿势

  • 50个最新TypeScript面试题合集[37]

事件循环

  • 宏任务、微任务

  • jwt、cookie登录态校验、公司项目前后端部署方式、虚拟化简单了解

git

  • 核心原理介绍

  • 常用操作

  • rebase、merge

  • 与工程化相关的操作

  • git diff文件对比算法思路

参考

  • HTTPS简介[38]

  • vue源码分析和对原理的理解[39]

  • 「面试题」20+Vue面试题整理[40]

[1]

从输入URL到浏览器显示页面过程中都发生了什么: https://juejin.cn/post/6905931622374342670

[2]

浏览器渲染页面过程: https://juejin.cn/post/6905931622374342670#heading-6

[3]

html文档解析为AST语法树: https://juejin.cn/post/6884791678582915086

[4]

css清除浮动: https://www.html.cn/qa/css3/13783.html

[5]

CSS 中你应该了解的 BFC: https://juejin.cn/post/6904568682555375624

[6]

Flex 布局教程:语法篇 - 阮一峰: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

[7]

工具网站: http://cubic-bezier.com/

[8]

CSS动画简介: http://www.ruanyifeng.com/blog/2014/02/css_transition_and_animation.html

[9]

javascript面试题整理: https://juejin.cn/post/6948600448388038670

[10]

vue面试题整理: https://juejin.cn/post/6947847527253311496

[11]

webpack打包原理&手写webpack核心打包过程: https://juejin.cn/post/6867471674183254024

[12]

在webpack-dev-server中添加mock中间件实现前端模拟数据功能: https://juejin.cn/post/6870326520246697997

[13]

webpack常用配置详解: https://juejin.cn/post/6870388131741302798

[14]

webpack配置优化: https://juejin.cn/post/6878098146530951176

[15]

vue路由懒加载: https://juejin.cn/post/6895546761255845901#heading-4

[16]

koa+mongondb实现用户登录注册模块: https://juejin.cn/post/6861797100834062343

[17]

nodejs的fs模块回调函数风格的异步操作转化为promise和await风格: https://juejin.cn/post/6870317049457934344

[18]

常见web攻击及防护方法: http://alanyf.site/blog/#/article/602883760181ed1bc8510b8a

[19]

HTTP1.0、HTTP1.1 和 HTTP2.0 的区别: https://www.cnblogs.com/heluan/p/8620312.html

[20]

ssl证书详细解读: http://www.jianshu.com/p/4494774963a9

[21]

常用设计模式分类: https://juejin.cn/post/6908528350986240014

[22]

单例模式(Singleton Pattern): https://juejin.cn/post/6885321951510790151

[23]

发布订阅模式(又叫观察者模式Observer Pattern): https://juejin.cn/post/6884900472344297485

[24]

中介者模式(Mediator Pattern): https://juejin.cn/post/6885306417264525325

[25]

策略模式(Strategy Pattern): https://juejin.cn/post/6904056276070694925

[26]

代理模式(Proxy Pattern): https://juejin.cn/post/6903725783085219853

[27]

迭代器模式(Iterator Pattern): https://juejin.cn/post/6904059710442307597

[28]

适配器模式(Adapter Pattern): https://juejin.cn/post/6904794930271485965

[29]

命令模式(Command Pattern): https://juejin.cn/post/6909253882217103374

[30]

组合模式(Composite Pattern): https://juejin.cn/post/6904095912851668999

[31]

总结

技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

1622374342670#heading-6_

[3]

html文档解析为AST语法树: https://juejin.cn/post/6884791678582915086

[4]

css清除浮动: https://www.html.cn/qa/css3/13783.html

[5]

CSS 中你应该了解的 BFC: https://juejin.cn/post/6904568682555375624

[6]

Flex 布局教程:语法篇 - 阮一峰: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

[7]

工具网站: http://cubic-bezier.com/

[8]

CSS动画简介: http://www.ruanyifeng.com/blog/2014/02/css_transition_and_animation.html

[9]

javascript面试题整理: https://juejin.cn/post/6948600448388038670

[10]

vue面试题整理: https://juejin.cn/post/6947847527253311496

[11]

webpack打包原理&手写webpack核心打包过程: https://juejin.cn/post/6867471674183254024

[12]

在webpack-dev-server中添加mock中间件实现前端模拟数据功能: https://juejin.cn/post/6870326520246697997

[13]

webpack常用配置详解: https://juejin.cn/post/6870388131741302798

[14]

webpack配置优化: https://juejin.cn/post/6878098146530951176

[15]

vue路由懒加载: https://juejin.cn/post/6895546761255845901#heading-4

[16]

koa+mongondb实现用户登录注册模块: https://juejin.cn/post/6861797100834062343

[17]

nodejs的fs模块回调函数风格的异步操作转化为promise和await风格: https://juejin.cn/post/6870317049457934344

[18]

常见web攻击及防护方法: http://alanyf.site/blog/#/article/602883760181ed1bc8510b8a

[19]

HTTP1.0、HTTP1.1 和 HTTP2.0 的区别: https://www.cnblogs.com/heluan/p/8620312.html

[20]

ssl证书详细解读: http://www.jianshu.com/p/4494774963a9

[21]

常用设计模式分类: https://juejin.cn/post/6908528350986240014

[22]

单例模式(Singleton Pattern): https://juejin.cn/post/6885321951510790151

[23]

发布订阅模式(又叫观察者模式Observer Pattern): https://juejin.cn/post/6884900472344297485

[24]

中介者模式(Mediator Pattern): https://juejin.cn/post/6885306417264525325

[25]

策略模式(Strategy Pattern): https://juejin.cn/post/6904056276070694925

[26]

代理模式(Proxy Pattern): https://juejin.cn/post/6903725783085219853

[27]

迭代器模式(Iterator Pattern): https://juejin.cn/post/6904059710442307597

[28]

适配器模式(Adapter Pattern): https://juejin.cn/post/6904794930271485965

[29]

命令模式(Command Pattern): https://juejin.cn/post/6909253882217103374

[30]

组合模式(Composite Pattern): https://juejin.cn/post/6904095912851668999

[31]

总结

技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

[外链图片转存中…(img-Q8zBmFpd-1715228044416)]

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值