Skip to content

阅读指引

  • 内容依照「CSS → 网络 → JavaScript → 工程化」划分,你可以直接用文档搜索 ## 进行跳转。
  • 每个问题都保留了面试高频问法,建议先自己作答,再展开对应的小节比对。
  • 需要延伸的知识点会在段尾附上关键词,例如 “HTTP/2 多路复用”,方便回到标准文档。

CSS

  • 左右两栏布局, 一侧定宽、一侧自适应撑满?

  • flex:1 代表什么?

直观的记忆是,如果设置了flex: 1,所有子项平分父亲,不管子项是否设置了固定宽度。

text
flex: 1 等价于
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
不管是否设置宽度,flex-basis的值都是0,所有子项平分全部的父亲空间

而flex: auto 等价于

flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
如果设置了宽度,flex-basis的值是width,所有子项平分取去掉flex-basis的剩余空间

网络

  • MQTT、Websocket、TCP 三者有什么区别?
js
1. 协议栈: 
  MQTTTCP 长链接、工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议
  HTTPTCP
2.  请求方式
  MQTT: 发布/订阅模式、提供一对多的消息发布、使用 TCP/IP 提供网络连接、有三种消息发布服务质量,  
  HTTP: 短连接、request/ response、基于TCP/IP通信协议来传递数据

JS

  • map 和 foreach 有什么区别
js
foreach()方法会针对每一个元素执行提供得函数,该方法没有返回值,是否会改变原数组取决与数组元素的类型是基本类型还是引用类型
map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值:
  • 说一下for...in 和 for...of的区别?
js
for...of遍历获取的是对象的键值, for...in获取的是对象的键名;
for...in会遍历对象的整个原型链, 性能非常差不推荐使用,而for...of只遍历当前对象不会遍历原型链;
对于数组的遍历,for...in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for...of只返回数组的下标对应的属性值;
总结:for...in循环主要是为了遍历对象而生,不适用遍历数组; for....of循环可以用来遍历数组、类数组对象、字符串、Set、Map以及Generator对象

1、请你讲一下闭包?

简单:闭包是有权限访问其他函数作用域内的变量的一个函数。

完整:由于在JS中,变量的作用域属于函数作用域,在函数执行后作用域就会被清理、内存也随之回收,但是由于闭包是建立在一个函数内部的子函数,由于其可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,这时的子函数——也就是闭包,便拥有了访问上级作用域中的变量的权限,即使上级函数执行完后作用域内的值也不会被销毁。

  • 闭包解决了什么?

由于闭包可以缓存上级作用域,那么就使得函数外部打破了“函数作用域”的束缚,可以访问函数内部的变量。以平时使用的Ajax成功回调为例,这里其实就是个闭包,由于上述的特性,回调就拥有了整个上级作用域的访问和操作能力,提高了极大的便利。开发者不用去写钩子函数来操作上级函数作用域内部的变量了。

  • 闭包有哪些应用场景?

闭包随处可见,一个Ajax请求的成功回调,一个事件绑定的回调方法,一个setTimeout的延时回调,或者一个函数内部返回另一个匿名函数,这些都是闭包。简而言之,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都有闭包的身影。

  • react hooks 中的 闭包陷阱问题如何解决?

不管在这个组件中的其他地方使用 setCount 将 count 设置为任何值,还是设置多少次,打印的都是1

jsx
function App(){
    const [count, setCount] = useState(1);
    useEffect(()=>{
        setInterval(()=>{
            console.log(count)
        }, 1000)
    }, [])
}

useRef

useState 更新值时传入回调函数

2、介绍一下 JS 里面的原型?

  • 所有原型链的终点都是 Object 函数的 prototype 属性

  • 每一个构造函数都拥有一个 prototype 属性,此属性指向一个对象,也就是原型对象

  • 原型对象默认拥有一个 constructor 属性,指向指向它的那个构造函数

  • 每个对象都拥有一个隐藏的属性 proto,指向它的原型对象

  • 原型的作用是什么?

共享方法

  • 原型中this的指向是什么?

原型中this的指向是实例。

  • 说一下平时开发使用到 prototype 的例子?

3、如何理解 es6 class 中 constructor 方法? 和 super的作用?

constructor 方法是类的构造函数。 通过 new 命令创建对象实例时,自动调用该方法。 constructor 内定义的方法是 实例方法;class 内直接定义的方法是原型方法。

  • super 的作用?

子类是没有自己的 this 对象的,它只能继承自父类的 this 对象,然后对其进行加工,而super( )就是将父类中的this对象继承给子类的。没有 super,子类就得不到 this 对象。

  • 为什么要传入 props?
jsx
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

确保了 this.props 在构造函数执行完毕之前已被赋值。

4、eventloop

浏览器或node 端 js 单线程运行时不会阻塞的一种机制。

任务分为宏任务和微任务;宏任务与微任务的区别?

宏任务:script全部代码、setTimeout、setInterval、I/O、UI Rendering。 微任务:Process.nextTick(Node独有)、Promise、Object.observe(废弃)、MutationObserver

  • 浏览器中的 event loop

JS 中有一个主线程和一个调用栈(执行栈),所有的任务都会被放到调用栈中等待主线程执行。

JS 调用栈后进先出原则,当函数执行的时候,会被添加到栈顶部,当执行完后,会被从栈顶移出,直到栈内被清空。

JS 任务分为同步任务和异步任务。同步任务在调用栈中按照顺序等待主线程依次执行。异步任务会在异步任务有结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),读取到栈内等待主线程执行。

任务队列:先进先出

顺序:同步任务 =》微任务 =》 宏任务

  • 执行栈在执行完同步任务后,查看执行栈是否为空
  • 如果执行栈为空,就会去检查微任务(microTask)队列, 执行完微任务,再执行宏任务
  • 每个宏任务执行完后,都会再检查微任务队列是否为空,不为空,就按先进先出执行完微任务,设置微任务为 null,再执行宏任务。

Node 中 event loop(待补充)

React

  • 怎么理解 React 中的副作用函数?

react 里面纯函数的概念:固定的输入有固定的输出,在 react 组件里面,通过 props 和 state,

1、介绍一下react diff 算法 的工作原理?

  • react 状态变化渲染页面时,不会马上对DOM节点进行操作,是先通过diff算法计算后,再对有变化的DOM节点进行操作。

  • diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处.

  • react中diff算法主要遵循三个层级的策略:tree层级、component 层级、element 层级

  • tree层级: DOM节点跨层级的操作不做优化,只会对相同层级的节点进行比较.只有删除、创建操作.新树中,R节点下没有了A,那么直接删除A,在D节点下创建A以及下属节点。

  • component 层级:是同一个组件,则会继续往下diff运算,如果不是一个类的组件,那么直接删除这个组件下的所有子节点,创建新的

  • element 层级:对于比较同一层级的节点们,每个节点在对应的层级用唯一的key作为标识.

    • 3 种节点操作,分别为 INSERT_MARKUP(插入)、MOVE_EXISTING (移动)和 REMOVE_NODE (删除)
    • 通过key可以准确地发现新旧集合中的节点都是相同的节点,因此无需进行节点删除和创建,只需要将旧集合中节点的位置进行移动,更新为新集合中节点的位置
    • 如果当前节点在新集合中的位置比老集合中的位置靠前的话,是不会影响后续节点操作的,这里这时候被动字节不用动
    • 当ABCD节点比较完成后,diff过程还没完,还会整体遍历老集合中节点,看有没有没用到的节点,有的话,就删除

由于dom节点的移动操作开销是比较昂贵的,没有key的情况下要比有key的性能更好

HTML
1.加key
<div key='1'>1</div>             <div key='1'>1</div>     
<div key='2'>2</div>             <div key='3'>3</div>  
<div key='3'>3</div>  ========>  <div key='2'>2</div>  
<div key='4'>4</div>             <div key='5'>5</div>  
<div key='5'>5</div>             <div key='6'>6</div>  
操作:节点2移动至下标为2的位置,新增节点6至下标为4的位置,删除节点4。

2.不加key
<div>1</div>             <div>1</div>     
<div>2</div>             <div>3</div>  
<div>3</div>  ========>  <div>2</div>  
<div>4</div>             <div>5</div>  
<div>5</div>             <div>6</div> 
操作:修改第1个到第5个节点的innerText

Virtual DOM 工作过程有:

1. state 变化,生成新的 Virtual Dom
2. 比较 Virtual Dom 与之前 Virtual Dom 的异同
3. 生成差异对象
4. 遍历差异对象并更新真实 DOM
  • React diff 算法 和 vue diff 的相同点和不同点有哪些?

不同点:

  • vue的列表比对,采用从两端到中间的比对方式,而react则采用从左到右依次比对的方式。当一个集合,只是把最后一个节点移动到了第一个,react会把前面的节点依次移动,而vue只会把最后一个节点移动到第一个
  • vue比对节点,当节点元素类型相同,但是className不同,认为是不同类型元素,删除重建,而react会认为是同类型节点,只是修改节点属性

Vue Diff使用双向链表,边对比,边更新DOM。React主要使用diff队列保存需要更新哪些DOM,得到patch树,再统一操作批量更新DOM。

相同点:

  • 虚拟DOM在比较时只比较同一层级节点,复杂度都为 O(n),降低了算法复杂度;
  • 都使用key比较是否是相同节点,都是为了尽可能的复用节点
  • 都是操作虚拟DOM,最小化操作真实DOM,提高性能(其实虚拟DOM的优势 并不是在于它操作DOM快)
  • 都是不要用 index作为 key

2、react 里什么是高阶组件?使用高阶组件的场景?

高阶组件(HOC)是接受一个组件并返回一个新组件的函数。

2、React setState 怎么获取到更新后的值?异步函数中为什么 setState 会立即更新?

3、useState 为什么不能放到条件语句里面?

React通过单链表来管理Hooks。 update 阶段,每次调用 useState,链表就会执行 next 向后移动一步。如果将 useState 写在条件判断中,假设条件判断不成立,没有执行里面的 useState 方法,会导致接下来所有的 useState 的取值出现偏移,从而导致异常发生。

4、说一下 useRef 有哪些用法?

useRef 除了获取 dom,另一个用法: 保存数据,不造成 rerender 想要保存数据,又不想触发函数的更新,该数据的更新不会造成组件 rerender

5、什么情况下使用 useCallback ? 子组件接收一个方法,避免子组件重复渲染

  • react 中只要父组件的 render 了,那么默认情况下就会触发子组的 render,react 提供了来避免这种重渲染的性能开销的一些方法:React.PureComponent、React.memo ,shouldComponentUpdate()
  • 使用 React.memo 避免子组件做没必要的渲染。
  • Reace.memo 只会对 props 做浅比较,也就是父组件重新 render 之后会传入 不同引用的方法 getList,浅比较之后不相等,导致子组件还是依然会渲染。
  • useCallback 缓存一个函数,当依赖没有改变的时候,会一直返回同一个引用

6、useCallback 与 useMemo 作用用来缓存,两者的区别是什么?

useMemo 缓存值;useCallback 缓存函数

注意不要滥用:

经常用在以下两种场景(要保持引用相等;对于组件内部用到的 object、array、函数等,如果用在了其他 Hook 的依赖数组中,或者作为 props 传递给了下游组件,应该使用 useMemo/useCallback)

7、react ssr 实现原理?react ssr 是在什么场景下做的?

server端接收到客户端的请求路由后,查找对应的数据,以props、context、store的形式注入组件中。然后基于react提供的API:renderToString将组件转换为html字符串输出到客户端。客户端使用该数据进行渲染,保证数据的一致性。

React SSR之所以能够实现,本质是虚拟 DOM的存在。判断环境是服务器环境,可以操作 JavaScript 对象,把虚拟 DOM 映射成字符串输出。判断环境是客户端环境,可以操作 JavaScript 对象,将虚拟 DOM 映射成真实 DOM ,完成页面挂载。

8、 react 项目里做过哪些性能优化?

代码层面:

  • 使用return null而不是CSS的display:none来控制节点的显示隐藏。保证同一时间页面的DOM节点尽可能的少。
  • props和state的数据尽可能简单明了,扁平化。
  • 不要使用数组下标作为key
  • 利用 shouldComponentUpdate 和 PureComponent 避免过多 render function
  • render里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。
  • 尽量将 props 和 state 扁平化,只传递 component 需要的 props(传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担),慎将 component 当作 props 传入

代码体积优化:

  • 使用 babel-plugin-import 优化业务组件的引入,实现按需加载
  • 使用 生产版本
  • 使用 SplitChunksPlugin 拆分公共代码
  • 分析 CSS 和 JS 代码覆盖率
  • 优化 Webpack 中的库
  • 使用动态 import,懒加载 React 组件
  • 使用 webpack-bundle-analyzer 可视化 webpack 输出文件的大小
  • 使用 Tree Shaking & 教程 & Tree Shaking 优化

9、有 用 过 lerna 吗 ? 多 个 项 目 之 间 共 用 的 东 西 怎 么 共 享 ?

10、使用 react 中,有没有遇到觉得比较难的点?是什么?

11、使用 hooks 中遇到过哪些坑?为什么?

  • 不要在循环,条件或嵌套函数中调用Hook,必须始终在React函数的顶层使用Hook。这是因为React需要利用调用顺序来正确更新相应的状态,以及调用相应的钩子函数。一旦在循环或条件分支语句中调用Hook,就容易导致调用顺序的不一致性。
  • 使用useState时候,使用push,pop,splice等直接更改数组对象的坑,应该采用析构方式.
  • 必包带来的坑,因为每次 render 都有一份新的状态,因此上述代码中的 setTimeout 使用产生了一个闭包,捕获了每次 render 后的 state,也就导致了输出了 0、1、2。如果你希望输出的内容是最新的 state 的话,可以通过 useRef 来保存 state。前文讲过 ref 在组件中只存在一份,无论何时使用它的引用都不会产生变化,因此可以来解决闭包引发的问题。

12、代码错误导致页面白屏问题,错误边界

Vue

1、Vue如何监听数组的变化?

  • 对象数据是怎么被监听的?

vue2.x版本中,数据监听用 Object.defineProperty. 通过Object.defineProperty来劫持对象属性的setter和getter操作,并创建一个监听器,当数据发生变化的时候发出通知

  • 数组数据是怎么被监听的?

Vue.js是基于Object.defineProperty对对象实现“响应式化”,而对于数组,Vue.js提供的方法是重写push、pop、shift、unshift、splice、sort、reverse这七个数组方法.

如果需要用数组下标修改数组并实现响应式数据变化,Vue.js提供了set()remove()方法。

1、Vue 组件 data 为什么必须是函数?

因为组件是可以复用的,JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染。 所以一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。

2、直接给一个数组项赋值,Vue 能检测到变化吗?

由于 Vue 会在初始化实例时对属性执行 getter/setter 转化,所以属性必须在 data 对象上存在才能让 Vue 将它转换为响应式的。

  • Vue 不能检测到以下数组的变动:

1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue

js
// 解决办法
vm.$set(vm.items, indexOfItem, newValue)

2.当你修改数组的长度时,例如:vm.items.length = newLength

js
/ 解决办法
vm.items.splice(newLength)
  • 检测不到的原因是什么?

当读取 obj.title 和修改 obj.title 的时候被 defineProperty 拦截,但 defineProperty 对不存在的属性无法拦截,所以 Vue 2 中所有数据必须要在 data 里声明。

但是,Vue 不能检测到对象属性的添加或删除。因为 Vue 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue 转换它,才能让它是响应的。需要额外的 $set。

3、vue2 中响应式(双向绑定)的原理?vue3 的原理? Proxy 与 Object.defineProperty 的优劣对比? 为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?

Proxy的优势如下: Proxy 可以直接监听对象而非属性 Proxy 可以直接监听数组的变化 Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的 Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改 Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利

Object.defineProperty 的优势如下:

兼容性好,支持 IE9

4、vuex 的工作流程是怎么样?

Vuex有5个重要的属性,分别是 State、Getter、Mutation、Action、Module,由 view 层发起一个 Action 给 Mutation,在 Mutation 中修改状态,返回新的状态,通过 Getter暴露给 view层的组件或者页面,页面监测到状态改变于是更新页面。

4、Vue 的初始化过程(new Vue(options))都做了什么?

处理组件配置项

初始化根组件时进行了选项合并操作,将全局配置合并到根组件的局部配置上

初始化每个子组件时做了一些性能优化,将组件配置对象上的一些深层次属性放到 vm.$options 选项中,以提高代码的执行效率

初始化组件实例的关系属性,比如 parentchildren、rootrefs 等

处理自定义事件

调用 beforeCreate 钩子函数

初始化组件的 inject 配置项,得到 ret[key] = val 形式的配置对象,然后对该配置对象进行响应式处理,并代理每个 key 到 vm 实例上

数据响应式,处理 props、methods、data、computed、watch 等选项

解析组件配置项上的 provide 对象,将其挂载到 vm._provided 属性上,如果 provide 是函数就用 call(vm) 方法 返回 provide 里面定义的对象

调用 created 钩子函数

如果发现配置项上有 el 选项,则自动调用 $mount 方法,也就是说有了 el 选项,就不需要再手动调用 $mount 方法,反之,没提供 el 选项则必须调用 $mount

接下来则进入挂载阶段

4、beforeCreate 期间能拿到数据吗?

不能,因为数据初始化阶段是在 beforeCreate 之后执行

4、Vue nextTick使用场景及实现原理

它主要是处理我们再变更完数据以后,无法立刻拿到最新的DOM节点对象的问题。

vue执行完渲染后会执行this.nextTick()里面的callback函数。

将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。

nextTick流程总结: 1、将回调放到callbacks里等待执行; 2、将执行函数(flushCallbacks)放到微任务或宏任务里;原码里按照是否原生支持Promise.then、MutationObserver和setImmediate的顺序决策,都不支持则使用setTimeout 3、等到事件循环执行到微任务或者宏任务时,执行函数依次执行callbacks里的回调;

5、Vue的nextTick具体是微任务还是宏任务?

宏任务微任务
setTimeoutprocess.nextTick
setIntervalMutationObserver
setImmediatePromise.then
requestAnimationFrame
MessageChannel

5、 Vue3 有哪些新的新特性?

  • 响应式系统
  • 自定义渲染器
  • 全部模块使用 TS 重构
  • Composition API 组合语法
  • 新一代工程化工具 Vite

6、Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?

vue2 问题:

  • 代码的可读性随着组件变大而变差

  • 每一种代码复用的方式,都存在缺点

  • TypeScript支持有限

  • 逻辑组织

    • 大型组件, 需要不断跳转代码块
    • 逻辑关注点相关的代码全都放在一个函数里
  • 逻辑复用

    • vue2 用 mixin去复用相同的逻辑, 我们一个组件混入大量不同的 mixins 的时候,命名冲突,数据来源不清
    • vue3 写 hook 函数

6、父组件可以监听到子组件的生命周期吗?

比如有父组件 Parent 和子组件 Child,如果父组件监听到子组件挂载 mounted 就做一些逻辑处理。

方法一:手动通过 $emit 触发父组件的事件

js
// Parent.vue
<Child @mounted="doSomething"/>
    
// Child.vue
mounted() {
  this.$emit("mounted");
}

方法二:父组件引用子组件时通过 @hook 来监听

js
//  Parent.vue
<Child @hook:mounted="doSomething" ></Child>
    
//  Child.vue
mounted(){
   console.log('子组件触发 mounted 钩子函数 ...');
},

@hook 方法不仅仅是可以监听 mounted,其它的生命周期事件,例如:created,updated 等都可以监听。

7、比较 Vue 和 React 两个框架,你觉得有哪些区别?

  • 监听数据变化的实现原理不同:

    Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化. react 中,数据变化后,通过新老数据的计算 Diff 来得知哪些数据发生变化。

  • 数据流的不同:

  • 模板渲染方式的不同:

8、什么是异步组件?

在声明或注册组件时,Vue 接受提供 Promise 的工厂函数。然后可以在调用该组件时对其进行“解析”。

js
new Vue({
    components: {
        ‘tweet-box’: () => import(‘./components/async/TweetBox’)
    }
});

http

1、HTTP有哪些请求方法?PUT 和 PATCH 有什么区别?

  • GET, POST 和 HEAD方法;OPTIONS, PUT, PATCH, DELETE, TRACE 和 CONNECT
  • PUT和PATCH都是更新资源,而PATCH用来对资源进行局部更新。

2、http 状态码 403 是什么错误?

  • 403 forbidden,表示对请求资源的访问被服务器拒绝

3、知道哪些 http 的缓存策略 ?控制缓存的请求头有哪些?

  • HTTP缓存机制分为强制缓存和协商缓存两类。
  • 强制缓存的意思就是不要问了(不发起请求),直接用缓存吧。
  • 强制缓存常见技术有Expires和Cache-Control。
  • Expires的值是一个时间,表示这个时间前缓存都有效,都不需要发起请求。
  • Cache-Control有很多属性值,常用属性max-age设置了缓存有效的时间长度,单位为秒,这个时间没到,都不用发起请求。
  • immutable也是Cache-Control的一个属性,表示这个资源这辈子都不用再请求了,但是他兼容性不好,Cache-Control其他属性可以参考MDN的文档。
  • Cache-Control的max-age优先级比Expires高。
  • 协商缓存是为了知道有没有更新,必须跟服务端沟通过才知道的。常见技术有ETag和Last-Modified。
  • ETag其实就是给资源算一个hash值或者版本号,对应的常用request header为If-None-Match。
  • Last-Modified其实就是加上资源修改的时间,对应的常用request header为If-Modified-Since,精度为秒。
  • ETag每次修改都会改变,而Last-Modified的精度只到秒,所以ETag更准确,优先级更高,但是需要计算,所以服务端开销更大。
  • 强制缓存和协商缓存都存在的情况下,先判断强制缓存是否生效,如果生效,不用发起请求,直接用缓存。如果强制缓存不生效再发起请求判断协商缓存。

Cache-Control,ETag,Last-Modified

其他

  • 怎么解决白屏问题?
js
1、加loading
2、骨架屏
  • webpack loader 和 plugin 区 别 ?
js
Loader:直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到`loader`。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。   
Plugin:直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
  1. 弱网环境下页面首屏如何快速加载?

    1.缓存的使用 2.SSR使用 3.骨架屏使用

  2. code review需要注意的点,你做code reivew的话,会重点查看哪里,怎么写出高内聚,低耦合的代码,以实习中遇到的一个通用组件实现举例。

  3. 什 么 是 TS 泛 型 ?

  4. webpack 构 建 流 程 是 怎 样 的 ?

  5. webpack 热 更 新 原 理 ?

  6. 有没有读过哪些源码?

  7. 最近开发的项目具体业务是怎么样的?介绍一下?

  8. 对前端而言,你觉得函数式编程体现在哪些方面?

    纯函数、不可变数据、高阶函数。 react 就是函数式思想,数据是不可变的,react 相当于纯函数,展示出来的 ui 就是结果。 redux 更是函数式思想

Devops 相关

Git

  • 常用 git 操作
js
git branch 查看本地所有分支
git status 查看当前状态 
git commit 提交 
git branch -a 查看所有的分支
git branch -r 查看远程所有分支
git commit -am "init" 提交并且加注释 
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上 
git remote show origin 显示远程库origin里的资源 
git push origin master:develop
git push origin master:hb-dev 将本地库与服务器上的库进行关联 
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git remote show 查看远程库
git add .
git rm 文件名(包括路径) 从git中删除指定文件
git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来
git config --list 看所有用户
git ls-files 看已经被提交的
git rm [file name] 删除一个文件
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
git commit -v 当你用-v参数的时候可以看commit的差异
git commit -m "This is the message describing the commit" 添加commit信息
git commit -a -a是代表add,把所有的change加到git index里然后再commit
git commit -a -v 一般提交命令
git log 看你commit的日志
git diff 查看尚未暂存的更新
git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git commit -m "remove" 移除文件(从Git中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git diff --cached 或 $ git diff --staged 查看尚未提交的更新
git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来

1、什么情况下使用 git rebase, 而不用 git merge

nginx

  1. 谈谈一下对 nginx 的理解,项目中用到 nginx 的哪些功能?
  • Nginx ,是一个 Web 服务器和反向代理服务器用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 协议。
  • 主要功能如下: 正向、反向代理 2、负载均衡、分流 3、虚拟主机(绑定host)

2、正向代理和反向代理区别是什么?

  • 正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定原始服务器,然后代理向原始服务器转交请求并将获得的内容返回给客户端。代理服务器和客户端处于同一个局域网内。
  • 比如说fanqiang。我知道我要访问谷歌,于是我就告诉代理服务器让它帮我转发。
  • 反向代理实际运行方式是代理服务器接受网络上的连接请求。它将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给网络上请求连接的客户端 。代理服务器和原始服务器处于同一个局域网内。
  • 比如说我要访问taobao,对我来说不知道图片、json、css 是不是同一个服务器返回回来的,但是我不关心,是反向代理 处理的,我不知道原始服务器。

3、nginx 如何来实现负载均衡?

负载均衡的5种策略:

sh
1.轮询(默认)
 每个请求按时间顺序逐一分配到不同的后端服务器

 upstream backserver {
    server 192.168.0.14;
    server 192.168.0.15;
}

2.weight
指定轮询几率,weight和访问概率成正比

upstream backserver {
    server 192.168.0.14 weight=3;
    server 192.168.0.15 weight=7;
}

3.ip_hash
已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的.ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。

upstream backserver {
    ip_hash;
    server 192.168.0.14:88;
    server 192.168.0.15:80;
}

4.fair
按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backserver {
    server server1;
    server server2;
    fair;
}

5.url_hash
按访问url的hash结果来分配请求,使每个url定向到同一个(对应的)后端服务器,后端服务器为缓存时比较有效。

upstream backserver {
    server squid1:3128;
    server squid2:3128;
    hash $request_uri;
    hash_method crc32;
}

docker

1、什么是 Docker?

  • Docker是一个容器化平台,它以容器的形式将您的应用程序及其所有依赖项打包在一起,以确保您的应用程序在任何环境中无缝运行。

2、Dockerfile中最常见的指令是什么?

  • FROM:指定基础镜像;LABEL:功能是为镜像指定标签;RUN:运行指定的命令;CMD:容器启动时要运行的命令。

3、docker 构建镜像多大,如何优化?

  • 使用轻量级基础镜像,如 Alpine
  • 多阶段构建

4、 CI 中前端镜像每次构建都很慢,甚至有时候失败,如何解决?

  • 合理分层,利用构建镜像缓存机制
  • 失败,检查是否安装依赖超时,修改 npm timeout

k8s

1、k8s是什么?请说出你的了解?

  • Kubernetes 是一个针对容器应用,进行自动部署,弹性伸缩和管理的开源系统。主要功能是生产环境中的容器编排。

2、k8s 集群里面最小的单位是什么?

  • pod 是最小单位。每个pod里边可以运行一个或多个container(容器)

3、Service这种资源对象的作用是什么?

  • 用来给相同的多个pod对象提供一个固定的统一访问接口,常用于服务发现和服务访问。

openstack

1、openstack 里 KeyStone 组件是用于提供什么服务的?Nova 组件是做什么用?

  • 认证服务(KeyStone) Nova – 用于在计算级别管理虚拟机,并在计算或管理程序级别执行其他计算任务。

Copyright ©2025 moweiwei