fix: 修改文章

This commit is contained in:
NICE CODE BY DEV 2023-10-30 09:41:14 +08:00
parent d7bfb9d8d4
commit b29ab2dce1
25 changed files with 422 additions and 229 deletions

View File

@ -9,49 +9,40 @@ group:
# 计算机原理
## 描述一下cookiessessionStorage 和localStorage的区别
- cookie 在浏览器和服务器之间来回传递SS和LS不会
- SS和LS 的储存空间更大
- SS和LS 有更多丰富易用的接口
- SS和LS 是有各自的储存空间
- LS 储存是永久性的SS 关闭浏览器就没了
## 如何实现浏览器内多个标签之间的通信
- 调用LS Cookies 等本地储存方式
- 调用LS Cookies 等本地储存方
## IE6 BUG 的解决办法
- 双边距float引起使用display
- 3像素问题float引起 使用displayinline-3px
- 超链接 hover 点击失效, 注意顺序
- 无法定义1px左右的宽度容器使用overflowhiddenzoom0.08line-height1px
## 你有哪些性能优化的方法
- 减少http请求次数cssjshtml压缩图片大小控制和压缩网页cdn托管data缓存图片服务器
- 前端模板 js + 数据减少由于html导致的带宽浪费减少请求次数
- 图片预加载,将样式表放在头部,脚本放在底部,加上时间戳
- 用innerHTML代替dom操作减少dom操作次数优化js性能
- 当需要设置的样式很多时设置className而不是直接操作dom
- 按需加载三方库、如果是单页应用则按需加载路由页面
- 开启gzip模式
- 避免在页面的主体布局中使用tabletable要在其中的内容完全下载完之后才会完全显示显示div+css布局慢。普通网站有一个普遍的思路就是尽量向前端化减少数据库操作减少磁盘IO
- 前端化:在不影响功能和体验的情况下,能在浏览器执行的不要在服务器执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取到的结果不要到外部取,本机能取到的不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询
- 前端化:在不影响功能和体验的情况下,能在浏览器执行的不要在服务器执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取到的结果不要到外部取,本机能取到的不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询多用localstoragesessionstorage、cookie
- 减少数据库操作指减少更新次数缓存结果减少查询次数将数据库执行的操作尽可能的让你的操作完成减少磁盘IO指尽量不适用文件系统作为缓存减少读写文件次数等。
- 程序优化永远要优化慢的部分
- 图片加载使用懒加载、列表滚动使用虚拟滚动
## http 状态码有哪些?分别代表啥意思?
@ -61,15 +52,23 @@ group:
- 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息
- 400-499 用于指出客户端的错误。
> 400: 语义有误 401当前请求需要用户验证 403: 服务器已经理解请求,但是拒绝执行他 404页面找不到
- 500-599 用于支持服务器错误。501 服务器不可用
## http 缓存策略
分为强制缓存和协商缓存。
强制缓存分为三种情况1. 没找到直接发起请求2. 找到了但是缓存结果没有失效直接使用缓存3. 找到了但是失效了就会去使用协商缓存
一般强制缓存的标识字段为 Expireshttp1.0,指定过期时间) 和 Cache-controlhttp1.1, public/private/no-cache/no-store,后者可以搭配 max-age 控制过期时间使用
协商缓存是强制缓存失效了,浏览器携带标识向服务端发起请求,服务器通过缓存标识决定是否使用缓存的过程。
协商缓存的字段为last-modified / if-modified-since 和 Etag / if-none-match后者优先级更高。
缓存的流程是请求报文向服务器发送last-modified 或者 etag字段如果和服务端对应的字段一致则服务端使用缓存返回304否则失效重新请求200
## 一个页面从输入 url 到页面显示完成,中间发生了什么?
@ -86,6 +85,7 @@ group:
> 解析对加载到的资源htmljscss进行语法解析建议相应的内部数据结构比如html的dom树js的属性表css的样式表规则等等
## 浏览器的渲染原理
![image.png](./img/htmlRender.png)
1浏览器会解析三个东西
@ -102,8 +102,8 @@ group:
3最后通过调用操作系统Native GUI的API绘制。
## 并发concurrency和并行parallelism区别
异步和这小节的知识点其实并不是一个概念,但是这两个名词确实是很多人都常会混淆的知识点。其实混淆的原因可能只是两个名词在中文上的相似,在英文上来说完全是不同的单词。

View File

@ -25,7 +25,7 @@ group:
- flex布局
> 设置justify-contentcenter
> 设置justify-contentcenteritems-align: center;
### 2· 垂直居中

View File

@ -9,6 +9,29 @@ group:
# 面试技巧
## 自我介绍技巧
1. 个人的基本情况介绍,简历上有的就大概跳过
2. 个人擅长什么,技术上的和非技术上的,技术上聊专长,非技术聊个人
3. 做过的项目,挑一些核心的说
4. 自己的一些想法和思考,兴趣和观点,让面试官感觉你是个爱折腾的人
举个例子:
--------------------------------
面试官好我叫dev18年毕业于东华理工大学软件工程从大四开始就一直从事前端开发的工作
我比较擅长的是 react 全家桶,平时开发的话,打包工具的话对 webpack 比较熟悉自己有从0-1大型项目的经验和能力包括前端项目的自动构建脚本编写项目服务器发布基本的node接口服务开发。服务器Nginx 的配置,负载均衡,域名服务器的配置,和使用 pm2 的去做项目的守护进程管理全链路开发。
在上家公司是人工智能创意中心视频编辑器的项目负责人主要职责是负责从0-1视频编辑器的开发和后期维护还有及时响应客户需求。在此期间还基于 yapi 搭建了一套接口自动化管理系统目的是为了高效对接后端接口质量自动化测试和解放手动编写接口的工作通过后端swagger文档自动生成包含ts注释的接口其它还负责公司的UI组件库的部分开发
除了开发相关的工作还有一定的作为Owner的项目管理经验比如需求评审UI\UX交互评审负责小组项目排期成员之间的协作开发监督成员之间的codeReview敏捷开发推动项目进度等。
另外我有自己的博客主要是用来记录在工作中的一些心得和碰到的问题和解决方案。同时去记录一些学到的新的知识早期也发过一些文章再segmentfault和掘金上。
在 github 上我还成立了一个自己的组织叫nicecode主要是用来沉淀一些这些年工作中整合的一些能提升工作效率的方案比如说脚手架、git提交校验工具、敏感字过滤库常见函数方法、还有开发过一款基于 vscode 的代码片段插件。前前后后写了10几个npm包了做这件事的原因是我感觉开源还挺有成就感也挺有趣的
--------------------------------
## 如何粗略判断公司是否靠谱
然后我们还得了解一家公司的情况,这里我推荐使用「天眼查」去查询一家公司的信息。在这里我们可以查询到一家公司的几个重要指标
@ -23,6 +46,40 @@ group:
很推荐大家在准备面试的过程中,挖掘出自己擅长的技术内容,然后在面试的过程中,寻找机会引导面试官提问你擅长的技术点。
### 常见问题答复
1. 你什么时候入职?
在职的时候说需要交接一下手续大概1-2礼拜。
离职的时候说:确定录用的话,大概一周左右时间可以入职。
2. 为啥工作换的这么频繁?
坦诚说,前几次的换工作让自己觉得在岗位持续发展和成长的重要性,所以现在希望找个好的平台固定下来,然后目前这个工作给我综合看来是比较合适的,所以非常希望能得到这个机会。
3. 为什么选择我们公司?
在对方讲完公司的优势之后,结合自身优点于成长诉求,表明与公司的契合度,营造平等的社交沟通
4. 为什么你觉得可以胜任这份工作?
从三个角度去展开:
* 工作经历、项目背景与当前岗位的匹配度
* 个人能力模型的匹配度
* 突出过往的工作中取得的成绩,竞争力优势
5. 你的期望薪资是多少?
最近我手里也有几个机会在看,大概就是在实际薪资的价位。但是我肯定会综合考量工作的价值,不会单纯地只看薪资。或者,您先报个价可以吗?
6. 接受加班吗?
赶项目、冲进度的时候,加班肯定在所难免。对于这些必要的加班,我一定会尽力配合。但是按照以往的经验来看,我会优先选择提高工作效率,而不是拉长工作时间。这样既能保证项目进度,也能让自己维持一个比较好的精神状态,迎接后续更大的挑战。
7. 为啥没干多久就离职了?
两个方面一个方面是和当初说好的不一样公司目前使用vue但是会用 react 重启新项目我认为做一件事专精很重要。另一方面加班比较多项目上线冲进度加班是正常且合理的但是经常周末需要加班晚上10-11点走CTO 倒排压缩开发时长不是很合理,生活和工作太不平衡,我不是很能接受
## 谈钱
具体的工资(也就是合同上签订的工资),不要杂七杂八什么绩效加起来的那种
@ -31,3 +88,7 @@ group:
是否是 996我个人很不推荐 996 的公司
加薪升职的情况
其他各种福利,比如餐补、房补、交通补、节假日福利、另外的保险等等
## 话术技巧参考
<https://juejin.cn/post/7173316141161381924>

View File

@ -19,9 +19,17 @@ group:
### typeof 返回哪些数据类型
- obj num fun bool undefined
- object number function boolean undefined
> typeof null 返回的是object这个是个历史遗留问题
> typeof null 返回的是 object这个是个历史遗留问题
### typeof 和 instanceof 的区别?
1. typeof 返回的是数据类型instanceof 返回的是布尔值
2. instanceof 可以判断复杂引用数据类型,但是不能判断基本数据类型
3. typeof 能判断基本数据类型,在引用类型中只能判断 function
> 通用检测数据类型可以采用Object.prototype.toString.call(),调用该方法,统一返回格式“[object Xxx]” 的字符串
### 3种强制类型转换两种隐式类型转换
@ -45,6 +53,7 @@ get: 1. 参数在链接上。2、url链接长度有限制所以大小有限
### call 和 apply 的区别
call可以允许多个参数入参而apply只允许一个参数
- object.call(this, obj1,obj2,obj3)
- object.apply(this, argument)
@ -57,7 +66,6 @@ get: 1. 参数在链接上。2、url链接长度有限制所以大小有限
### 添加 删除 替换 插入到某个节点的方法
- obj.appendChild()
- obj.innersetBefore()
- obj.replaceChild()
@ -73,18 +81,20 @@ get: 1. 参数在链接上。2、url链接长度有限制所以大小有限
```javascript
function A(name) {
this.name = name;
this.sayHello = function(){alert(this.name+ "say hello!")}
function A(name) {
this.name = name;
this.sayHello = function() {
alert(this.name+ "say hello!")
}
}
function B(name, id) {
this.temp = A
this.temp(name)
delete this.temp
this.id = id
this.checkId = function(ID) {alert(this.id == ID)}
}
function B(name, id) {
this.temp = A
this.temp(name)
delete this.temp
this.id = id
this.checkId = function(ID) {alert(this.id == ID)}
}
```
@ -92,125 +102,45 @@ get: 1. 参数在链接上。2、url链接长度有限制所以大小有限
```javascript
function stopBubble(e) {
if (e && e.stopPropagation) {
e.stopPropgation ()
} else {
window.event.cancelBubble = true
}
return false
}
function stopBubble(e) {
if (e && e.stopPropagation) {
e.stopPropgation ()
} else {
window.event.cancelBubble = true
}
return false
}
```
### 谈谈this对象的理解
### 谈谈 this 对象的理解
- this只在调用的时候发生指向确认它指向什么取决于在什么地方调用。this 指向的就是调用函数的那个对象。
- this 一般情况下: 是指全局对象global 如果作为方法调用,就指向这个对象
- 对于直接调用 foo 来说,不管 foo 函数被放在了什么地方this 一定是 window
- 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this所以在这个场景下 foo 函数中的 this 就是 obj 对象
- 对于 new 的方式来说this 被永远绑定在了 c 上面,不会被任何方式改变 this
- 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this所以在这个场景下 foo 函数中的 this 就是 obj 对象(箭头函数则指向window)
- 对于 new 的方式来说this 被永远绑定在构造函数上面,不会被任何方式改变 this
```js
console.log(this)
class Test {
constructor() {
console.log(this)
}
}
export default () => {
let demo = new Test()
}
```
### 简单讲下 node 的使用场景
- 高并发,聊天,实时消息推送
### node 的优点和缺点提出自己的看法
- 优点: node是基于时间驱动和无阻塞的所以非常适合处理并发请求因此构建在node上的代理服务器相比其他技术实现的服务器表现要好的多与node代理服务器交互的客户端代码也是用js写的用的相同的语言这感觉前后端非常亲切和美妙
- 缺点: node是一个相对比较新的开源项目所以不太稳定它总是在变而且缺少足够多的第三方库的支持
### `location.replace()`与`location.assign()`区别
```html
location.replace() 的 url 不会出现在 history 中
```
### AMD CMD CommonJS
### DOM 操作
#### Common.js
```html
主要是服务端前期的nodejs采用了这种规范。module.exports或exports负责对外暴漏数据require来引入
<!--a.js-->
module.exports = {
name: '四大名将'
}
<!--也可以用exports导出-->
<!--export.name = '四大名将'-->
<!--b.js-->
const res = require('./a.js')
console.log(res.name) // 四大名将
```
#### AMD: 加载完成后执行
```html
客户端加载时需要等待可能存在假死情况鉴于浏览器的特殊情况AMD规范出来了
它采用异步方式加载模块定义的所有依赖,在依赖加载完成后再执行回调函数。
<!-- 定义模块 -->
<!-- AMD中require的模块会先加载完成 依赖前置 提前执行 -->
define('module', ['dep1', 'dep2'], function(dep1, dep2){
  function foo(){
dep1.doSomething();
dep2.doSomething();
  }
  return {
    foo : foo
  };
})
<!-- 数组中声明需要加载的模块可以是模块名、js文件路径 -->
<!-- 两个参数:加载的模块,加载成功后的回调函数 -->
require(['module'], function(module){
module.foo()
});
```
#### CMDrequire 到依赖才执行
```html
CMD规范在2011年由seaJS提出CMD规范和AMD规范类似主要区别是CMD规范是就近加载依赖
延迟执行只有到require时依赖才执行。
<!-- a.js -->
define(function(require, exports, module) {
function foo(){
<!-- require的模块此时才会执行 依赖就近 延迟执行 而AMD中依赖是前置的 一开始就全都执行完毕了 -->
var dep1 = require('dep1')
dep1.doSomething();
 }
 <!--暴漏给外部调用-->
 exports.foo = foo
 
 /** return或者exports都行
 return {
  foo : foo
 };
 **/
});
<!-- b.js -->
seajs.use("./a", function(a){
a.foo()
});
```
#### DOM 操作
```html
// 创建节点
createDocumentFragment()
@ -232,8 +162,8 @@ querySelector()
querySelectorAll()
```
### JS设置css样式的几种方式
```html
/* 1.直接设置style属性 */
element.style.height = '100px';
@ -253,6 +183,7 @@ element.style.cssText += 'height: 100px !important';
### 阻止默认行为
```html
function stopDefault( e ) {
// 阻止默认浏览器动作(W3C)
@ -266,8 +197,8 @@ function stopDefault( e ) {
}
```
### 阻止冒泡
```html
function stopBubble(e) {
// 如果提供了事件对象则这是一个非IE浏览器
@ -281,8 +212,8 @@ function stopBubble(e) {
}
```
### Ajax交互过程
```html
创建XMLHttpRequest对象,也就是创建一个异步调用对象.
创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
@ -291,8 +222,11 @@ function stopBubble(e) {
获取异步调用返回的数据.
使用JavaScript和DOM实现局部刷新.
```
### 考察知识点最广的JS面试题
[https://www.cnblogs.com/xxcanghai/p/5189353.html](https://www.cnblogs.com/xxcanghai/p/5189353.html)
```html
function Foo() {
getName = function () { alert(1); }
@ -314,9 +248,22 @@ new Foo().getName();
new new Foo().getName();
```
### splice和slice你能说说有啥用和区别吗
1. splice是可以实现数组的增删改查、只对数组生效会改变原数组
2. slice不光可以截取数组也可以截取字符串不会改变原数组
### 类数组和数组的区别
1. 类数组不具备数组的方法slice、splice、filter
2. 类数组是一个普通对象,数组类型是 Array
### JS数组深浅拷贝
#### 浅拷贝
把一个对象的第一层拷贝到新的对象上去,只拷贝基本数据类型
```javascript
// slice 实现
var arr = ['old', 1, true, null, undefined];
@ -339,8 +286,10 @@ console.log(arr) // ["old", 1, true, null, undefined]
console.log(new_arr) // ["new", 1, true, null, undefined]
```
#### 深拷贝
拷贝所有类型的数据类型,不同的方法会有不同的克隆效果
```javascript
// 简单版:不能拷贝 函数、undefined、symbol 、循环引用的对象
var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}];
@ -458,15 +407,6 @@ function type (obj) {
}
```
### typeof 和 instanceof 的区别?
```javascript
typeof 在原始类型中无法判断 null在对象类型中只能判断 object 和function
instanceof 可以判断对象类型的
```
### 防抖
```javascript
/*
@ -528,9 +468,9 @@ var debounce = function (func, wait, immediate) {
定义:函数 A 中有一个函数 B函数 B 可以访问 A 的变量,那么函数 B 就是闭包。
- 闭包就是能够读取其他函数内部变量的函数
- 闭包就是引用其他函数内部变量的函数
#### 循环中使用闭包解决 `var` 定义函数的问题
1. 循环中使用闭包解决 `var` 定义函数的问题
```javascript
方法1
for (var i = 1; i <= 5; i++) {
@ -553,11 +493,56 @@ for (var i = 1; i <= 5; i++) {
}
方法3使用 let
for (let i = 1; i <= 5; i++) {
setTimeout(
function timer(j) {
console.log(j)
},
i * 1000,
i
)
}
```
2. react 自定义 hooks 也属于闭包
```js
const useCount = () = {
let count = 0
const getCount = () => {
return count
}
const setCount = (num: number) => {
count = num
}
return {
getCount,
setCount
}
}
```
3. 函数的柯里化
4. 回调函数
```js
const fn = (cb: (name: string) => void) => {
let name = 'nicecode'
cb(name)
}
```
### 如何理解原型?如何理解原型链?
原型的本质就是一个对象我们创建一个构造函数的时候它自动会带上一个prototype属性这个属性就指向原型对象。它的作用就是用来提供基于函数原型继承的共享属性
当读取实例的属性获取不到时,如果找不到,就会查找与对象关联的原型中的属性,还找不到就会去找原型的原型,一直到顶层,这样的一层层的关系嵌套称为**原型链**
1. 每一个对象都有**__proto__**这是浏览器早期为了让我们能访问 prototype。
2. _ _proto__ 的 constructor构造函数里面有 prototype。
3. _ _proto__ 下面有几个方法hasOwnProperty 、toString、toLocalString、valueOf、isPrototypeOf
@ -571,7 +556,6 @@ promise 的出现是为了解决回调地狱callback hell它的其他AP
1. all处理所有promise事件回调的合集
```js
let p1 = new Promise(function(resolve, reject) { resolve('ok1') })
let p2 = new Promise(function(resolve, reject) { resolve('ok2') })
@ -600,12 +584,13 @@ let res = Promise.race([p1,p2]).then(res => console.log(res)) // ok1
### 手写一个 promise
```jsx
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
const PENDING = 'PENDING'; // 处理中
const FULFILLED = 'FULFILLED'; // 已完成
const REJECTED = 'REJECTED'; // 已拒绝
class Prom {
constructor(executor) {
// 默认状态为 PENDING
@ -613,7 +598,7 @@ class Prom {
// 存放成功状态的值,默认为 undefined
this.value = undefined;
// 存放失败状态的值,默认为 undefined
this.reason = undefined;
this.error = undefined;
let resolve = (val) => {
if (this.status === PENDING) {
@ -625,13 +610,13 @@ class Prom {
let reject = (err) => {
if (this.status === PENDING) {
this.status = REJECTED
this.reason = err
this.error = err
}
}
try {
// 立即执行,将 resolve 和 reject 函数传给使用者
executor(resolve,reject)
executor(resolve, reject)
} catch (error) {
// 发生异常时执行失败逻辑
reject(error)
@ -650,22 +635,25 @@ class Prom {
}
export default() => {
const [text, setText] = useState(PENDING)
useEffect(() => {
const promise = new Prom((resolve, reject) => {
resolve('成功');
}).then(
(data) => {
console.log('success', data)
setText(data)
console.log('手写promise', data)
},
(err) => {
setText(err)
console.log('faild', err)
}
)
}, [])
return (
<div>Promise</div>
<div>{text}</div>
)
}
@ -677,18 +665,24 @@ export default() => {
## 柯里化
```jsx
特点:
1. 组合函数:可以将函数的逻辑简单化,并且达到更细粒度的代码拆分和复用
2. 延迟执行:可以延迟执行最后一个参数执行的时间,在期间做一些其他逻辑的执行,剩余的到后面再决定
3. 简单化函数:将参数从多参数拆为单参数,让接口简洁,更容易使用
```js
import React, { useEffect } from 'react';
function curry(val) {
return function() {
function curry(a: number) {
return function(b: number) {
return function(offset: number) {
return a + b + offset
}
}
}
export default () => {
curry(1)()
curry(1)(2)(3)
return (
<div>柯里化函数</div>
@ -696,66 +690,72 @@ export default () => {
}
```
## 十大错误
### 1. Uncaught TypeError: Cannot read property
## event loop
js 执行的过程中,会创建对应的执行上下文放入栈中,我们称之为执行栈,其中执行栈中的任务又会分为宏任务和微任务。按照流程执行就是一次宏任务的进行结束之后,查看是否有微任务,执行微任务,微任务执行完毕,再一次执行宏任务,就是所谓的 event loop
宏任务大概有setTimeout()、setInterval()、setImmediate()、I/O、用户交互操作UI渲染
微任务则有promise.then()、promise.catch()、new MutationObserver、process.nextTick()
## 堆、栈的区别
1. 基本数据类型一般内存小,放在栈中;引用数据类型一般内存大,放在堆中
2. 栈的垃圾回收是执行环境结束立即释放,而堆需要所有引用结束才会释放
3. 一般来说栈的效率要高于堆
## v8的垃圾回收机制
执行js的过程中根据对象的存活时间进行不同的分代然后根据不同的分代采用不同的回收算法
新生代的空间换时间 scavenge 算法是1. 执行的过程中将空间分为 From 和 To 两块2. 判断是否满足存活条件存活的将变量复制到另一个空间3. 不存活的直接清理。4. 将From 和 To 空间交换,如此循环往复
老生代的标记清除和整理,运行的时候将活跃的变量标记,并进行整理到内存的一端,移除那些不活跃的空间进行释放回收
## 十大错误
### 1. Uncaught TypeError: Cannot read property
发生这种情况的原因很多,但常见的一种是在渲染 UI 组件时对于状态的初始化操作不当。
### 2. TypeError: undefined is not an object
这是在 Safari 中读取属性或调用未定义对象上的方法时发生的错误。这与 1 中提到的 Chrome 的错误基本相同,但 Safari 使用了不同的错误消息提示语。
### 3. TypeError: null is not an object
这是在 Safari 中读取属性或调用空对象上的方法时发生的错误。
> 在 JavaScript 中null 和 undefined 是不一样的这就是为什么我们看到两个不同的错误信息。undefined 通常是一个尚未分配的变量,而 null 表示该值为空。 要验证它们不相等,请尝试使用严格的相等运算符 ===
### 4. (unknown): Script error
当未捕获的 JavaScript 错误通过window.onerror处理程序引发的错误而不是捕获在try-catch中被浏览器的跨域策略限制时会产生这类的脚本错误。这是一种浏览器安全措施旨在防止跨域传递数据否则将不允许进行通信。
### 5. TypeError: Object doesnt support property
这是您在调用未定义的方法时发生在 IE 中的错误。 您可以在 IE 开发者控制台中进行测试。
### 6. TypeError: undefined is not a function
当您调用未定义的函数时,这是 Chrome 中产生的错误。
### 7. Uncaught RangeError: Maximum call stack
这是 Chrome 在一些情况下会发生的错误。 一个是当你调用一个不终止的递归函数。
### 8. TypeError: Cannot read property length
这是 Chrome 中发生的错误,因为读取未定义变量的长度属性。
### 9. Uncaught TypeError: Cannot set property
当我们尝试访问一个未定义的变量时,它总是返回 undefined我们不能获取或设置任何未定义的属性。 在这种情况下,应用程序将抛出 “Uncaught TypeError: Cannot set property”。
### 10. ReferenceError: event is not defined
当您尝试访问未定义的变量或超出当前范围的变量时,会引发此错误。
## 参考文章
<https://github.com/CavsZhouyou/Front-End-Interview-Notebook>

105
docs/interview/node.md Normal file
View File

@ -0,0 +1,105 @@
---
nav:
title: 面试
path: /interview
group:
title: 💊 面试题库
order: 8
---
# Node
## ESM和CJS 的区别
### ESM
1. ESM 模块是引用import重新赋值会报错不能改变指针指向但是可以改变内部的值
2. import 是只读引用
3. ESM 引用是动态引用
### CJS
1. CJS 是属于浅拷贝,可以重新赋值,可以修改指针
2. 对于基本数据类型属于复制
3. 复杂数据类型属于浅拷贝,由于两个模块指向同一个内存空间,因此对一个模块的改变会影响另一个模块
### 简单讲下 node 的使用场景
- 高并发,聊天,实时消息推送
### node 的优点和缺点提出自己的看法
- 优点: node是基于时间驱动和无阻塞的所以非常适合处理并发请求因此构建在node上的代理服务器相比其他技术实现的服务器表现要好的多与node代理服务器交互的客户端代码也是用js写的用的相同的语言这感觉前后端非常亲切和美妙
- 缺点: node是一个相对比较新的开源项目所以不太稳定它总是在变而且缺少足够多的第三方库的支持
### AMD CMD CommonJS
#### Common.js
```html
主要是服务端前期的nodejs采用了这种规范。module.exports或exports负责对外暴漏数据require来引入
<!--a.js-->
module.exports = {
name: '四大名将'
}
<!--也可以用exports导出-->
<!--export.name = '四大名将'-->
<!--b.js-->
const res = require('./a.js')
console.log(res.name) // 四大名将
```
#### AMD: 加载完成后执行
```html
客户端加载时需要等待可能存在假死情况鉴于浏览器的特殊情况AMD规范出来了
它采用异步方式加载模块定义的所有依赖,在依赖加载完成后再执行回调函数。
<!-- 定义模块 -->
<!-- AMD中require的模块会先加载完成 依赖前置 提前执行 -->
define('module', ['dep1', 'dep2'], function(dep1, dep2){
  function foo(){
dep1.doSomething();
dep2.doSomething();
  }
  return {
    foo : foo
  };
})
<!-- 数组中声明需要加载的模块可以是模块名、js文件路径 -->
<!-- 两个参数:加载的模块,加载成功后的回调函数 -->
require(['module'], function(module){
module.foo()
});
```
#### CMDrequire 到依赖才执行
```html
CMD规范在2011年由seaJS提出CMD规范和AMD规范类似主要区别是CMD规范是就近加载依赖
延迟执行只有到require时依赖才执行。
<!-- a.js -->
define(function(require, exports, module) {
function foo(){
<!-- require的模块此时才会执行 依赖就近 延迟执行 而AMD中依赖是前置的 一开始就全都执行完毕了 -->
var dep1 = require('dep1')
dep1.doSomething();
 }
 <!--暴漏给外部调用-->
 exports.foo = foo
 
 /** return或者exports都行
 return {
  foo : foo
 };
 **/
});
<!-- b.js -->
seajs.use("./a", function(a){
a.foo()
});
```

View File

@ -11,16 +11,12 @@ group:
## 1. 不要用 Eval
eval 的作用是将用户输入的字符串转化为可执行的代码,类似欺骗的效果,这样的坏处是会受到 XSS 攻击。
## 2. 使用 strict 模式
严格模式下的变量 **重复声明** 等操作会抛出一些隐藏的错误。
```javascript
'use strict'
var obj = {
@ -30,42 +26,30 @@ var obj = {
// 抛出错误 syntax error
```
## 3. 使用 Eslint 测试代码规范
可以使我们早期捕获一些 bug并及时修正。
## 4. 全面测试
测试很重要,不但单元要测试,还要全面测试,例如用 mocha 测试代码覆盖率。
测试很重要,不但单元要测试,还要全面测试,例如用 mocha 测试代码覆盖率。使用 jest 进行单元测试
## 5. Unix 下不要直接使用 sudo node app.js
这样如果产生错误,会让整个系统宕机,可以使用 nginx 反向代理。
## 6. 避免 shell command 注入
```-t
child_process.exec('ls', function (err, data) {
console.log(data);
});
```
上面的 child_process.exec 调用的是 /bin/sh ,也就是执行了一个解释器。
> 为了避免这个问题我们可以使用child_process.execFile。
## 7. 临时文件
@ -74,8 +58,6 @@ child_process.exec('ls', function (err, data) {
> 使用 Streams。
## 8. 加密 Web 应用
@ -96,26 +78,35 @@ Im human <script>alert('Im hacker')<script>
> 处理方式1. 对插入的数据进行验证,除去 HTML。
## 10. 看好你的 cookie
默认情况下cookie 可以通过 js 在同一个域中读取,这就有可能会被跨站点脚本攻击,而且可能被第三方库读取。为了处理这种情况,我们可以在 cookies 上使用 HTTPOnly这个标签可以让 js 无法读取。
## 11. 内容安全策略CSP
附加的安全层可以检测和缓解某类攻击例如XSS、数据注入。启用方法如下
```-t
Content-Security-Policy: default-src 'self' *.mydomain.com
```
## 12. Cross-Site Request Forgery
跨站请求伪造是一种迫使终端用户在他目前已验证授权的Web应用程序中执行其它的actions。node 社区已实现,可以使用同步令牌模式处理。
## react 性能提升的几个方式
1. 如果是18之前可以将版本提升挂载改成 createRoot优化后的算法会比之前的强。
2. prerender 预加载首屏页面,提升网页的收录
3. 给页面添加 loading增加用户体验可以通过 webpack 配置
4. 通过请求头的时间限制来达到缓存的效果,协商缓存和强制缓存,节省浏览器的支出
5. 动态引入polyfill我们市面上90%以上的设备其实都能支持最新的API但是如果我们为了这10%的不支持用户从而去放弃90%的人的用户体验不值得,让它通过 UA 请求头来判断是否需要加载polyfill.
6. 使用 splitChunkPlugin 分离公共方法和独立的页面代码,提升复用率和加载速度
7. 使用 DllPlugin抽离一些公共包提升打包时间这个包只有在版本变化的时候才会去重新打包
8. tree shakingwebpack4.0是默认打开的
9. code splitting 按需加载页面的某个模块,提升页面加载速度
10. 使用 placeholder 和 lazy-load 提升页面性能
## 参考文章
源码分析<https://react.iamkasong.com/#%E7%AB%A0%E8%8A%82%E8%AF%B4%E6%98%8E>

View File

@ -13,37 +13,37 @@ google 出品的一款前端MVC框架将所有可视化模块组件化
## 为什么选择 react 框架而不是原生js
1. 提升复用率,组件化的开发形式代码的复用率更高,交付更快,拓展性更强
2. 生态成熟目前基于react的生态圈比较完善可以更快提升开发的效率
3. 相比较早年的js + jq的开发形式MVC结构能够更好的提升代码的易读性让开发更加清晰
1. 复用率高:组件化的开发形式代码的复用率更高,交付更快,拓展性更强
2. 生态成熟目前基于react的生态圈比较完善可以更快提升开发的效率
3. 可读性强:相比较早年的js + jq的开发形式MVC结构能够更好的提升代码的易读性让开发更加清晰
## 什么是 fiber 架构
react 需要经历两个阶段:
1. 将jsx转换成 AST 结构
2. 新老ast结构进行比较,让后更新渲染到页面上
2. 新老 AST 结构进行比较,让后更新渲染到页面上
16以前的版本是将更新渲染直接入栈出栈队列执行diff算法本质上是一种递归递归无法中断这种形式可能会由于IO堵塞从而导致页面卡顿丢帧。
而fiber架构有效的改良了这一点使用的是一种循环机制将整个任务渲染切片成无数个小任务发放到每个细分的时间节点中执行优先处理最紧急的任务有效降低了卡顿的情况发生。
另外我们需要了解人眼的
![image.png](./img/fiber.jpeg)
## hooks 相比较传统 class 组件的区别
## hooks组件 相比较传统 class组件 的区别
## 优点
1. 解决了 HOC 的嵌套问题,扁平式状态逻辑更加简洁
2. 解决了类组件的 this指向问题
2. 解决了类组件的 this 指向问题
3. 分割在不同生命周期的代码使得代码难以维护
4. 降低代码的复用成本减少每个组件继承react.component,大大提升性能
## 缺点
1. 额外的学习成本
2. 没有类组件的生命周期也就没办法和ComponentUpdate一样获取组件上的新旧数据做比较
2. 没有类组件的生命周期,也就没办法和 ComponentUpdate 一样获取组件上的新旧数据做比较(性能优化上就少了一环)
## memo 和 PureComponent
@ -65,10 +65,12 @@ const Component = React.memo(() => {
})
```
## useMeno
## useMemo
将计算结果缓存下来,一般使用在比较复杂的计算函数中,降低大量计算的时候时间和性能上的消耗。
一般是如果一个引用数据会在多个hook里被使用或者是需要以 props 的形式传递给子组件,则需要包裹。
```jsx
import React, { useMemo, useEffect, useState } from 'react'
@ -101,7 +103,9 @@ export default () => {
## useCallback
基本上和 useMemo 代码逻辑是一样的只是useCallback 相比较 useMemo是将函数缓存下来防止执行其他操作的时候多次渲染消耗性能。需要搭配meno一起使用。
基本上和 useMemo 代码逻辑是一样的只是useCallback 相比较 useMemo是将函数缓存下来防止执行其他操作的时候多次渲染消耗性能。需要搭配memo一起使用。
使用原则也和 useMemo 保持一致
```jsx
import React, { useEffect, useCallback, useState } from 'react'
@ -159,7 +163,7 @@ export default () => {
```js
import React, { lazy, Suspense } from 'react'
const Comp = React.lazy(() => {
const Comp = lazy(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(import(/*webpackChunkName:"OtherComponent"*/'./OtherComponent'))
@ -213,7 +217,8 @@ export default () => {
1. 将要装载在render之前调用
2. 可以在服务端被调用,也可以在浏览器端被调用;
3. componentWillMount 每一个组件render之前立即调用
3. componentWillMount 每一个组件render之前立即调用
4. 目前在17中已经遗弃了这个接口前缀为 UNSAFE_
### componentDidMount
@ -244,7 +249,7 @@ function useState(initData) {
redux 分为几个重要的概念1. store容器、2. state数据、3. action动作、4. reducer计算动作过程、5. dispatch事件分发
工作过程dispatch通过调用action执行一个事件store自动调用reducer对state进行变更state变更同时view也产生变化
工作过程dispatch 通过调用 action 执行一个事件store 自动调用 reducer state 进行变更state 变更,同时 view也产生变化
## 参考文档

View File

@ -10,3 +10,35 @@ group:
# Typescript
目前市面上比较流行的js的超集目的是为了让js更加的严格向强类型的语言看齐同时为了后期维护上的便利。
## interface 和 type 的区别
interface 更偏向结构定义type更偏向数据之间的关系
1. 两者继承的方式不同
```js
interface App extends Module {
}
type App = Module & { name: string }
```
2. type 可以神秘基本数据类型、联合类型、元祖类型interface不能
```js
type Name = string
type Pet = Dog | Cat
type PetList = [Dog, Cat]
```
3. type 可以使用 typeof 获取类型interface不行
```js
const Name = 'nicenote'
type Iname = typeof Name
```

View File

@ -54,7 +54,6 @@ yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel
### centos 快速安装
- yum install nginx -y
## 常用命令
### 查看 nginx 配置文件路径和安装路径

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,10 +1,10 @@
---
<!-- ---
nav:
title: 关于我
path: /resume
group:
order: 99
gapless: true
---
--- -->
<code src="./index.tsx" inline />
<!-- <code src="./index.tsx" inline /> -->