生命在于折腾。做成一件事情时,不要特别放大自己;事情没做好,也不用气馁。 一定要相信我是牛逼的,这件事情不行没有关系,我接着做下一个,我死之前一直干,早晚能成。
2022-10-14
1. 进行SEO优化需要注意什么?
参考答案
- 合理的title、description、 keywords:搜索对着三项的权重逐个减小,title强调重点,description把页面内容高度概括(不可过分堆砌关键词)、keywords列出重要关键词。
- 重要内容不用js输出,爬虫不会执行js获取内容
- 非装饰性图片必须加alt
- 提高网站速度(网站速度是搜索引擎排序的一个重要指标)
- 谨慎使用display属性
- 减少使用iframe框架
- 服务端渲染 ……
2. React的有哪些限制以及JSX是什么 【React】
参考答案
React的限制如下:
- React 只是一个库,而不是一个完整的框架
- 它的库非常庞大,需要时间来理解
- 新手程序员可能很难理解
- 编码变得复杂,因为它使用内联模板和 JSX
JSX
- JSX 是J avaScript XML 的简写。是 React 使用的一种文件,它利用 JavaScript 的表现力和类似 HTML 的模板语法。这使得 HTML 文件非常容易理解。此文件能使应用非常可靠,并能够提高其性能
3.babel插件与预设的理解 【babel】
参考答案
- babel的核心是插件,babel的所有工作都是由插件完成的。
- babel预设是指:将一系列的常用插件集中在一个篮子里
babel/preset-env
,这样就不用单独的去一个一个安装babel提高的必要插件了 。
{
"plugins": [],
"presets": [
"@babel/preset-env"
]
}
4. Webpack中loader与plugin的区别,以及如何自定义 【Webpack】
参考答案
区别
- loader本身就只是一个函数,在该函数中对接收到的内容进行转换。它是个翻译官,它在modules的rules中配置,内部包含test、loader和options属性。
- Plugin就是插件,基于事件流。Webpack在运行当中会去广播一些事件,plugin去监听这些事件,然后干活。plugin单独配置,通过构造函数传入参数生效。
自定义loader
- loader本质上是一个函数
- 因为函数中的this作为上下文会被webpack填充,因此不能将loader设为一个箭头函数
- 该函数接受一个参数,这个参数是webpack传递给loader的文件源内容
自定义Plugin
- webpack编译会创建两个核心对象:compiler和compilation
- compiler:包含了webpack环境的所有配置消息,包括options、loader和plugin,以及webpack整个生命周期相关的钩子
- compilation:作为Plugin内置事件回调函数的参数,包含了当前的模块资源、编译生成资源、变化的文件以及被跟踪依赖的状态信息。当检测到一个文件变化,一次新的compilation将被创建
// 导出一个函数,其中source为webpack传递给loader的输入参数--文件源内容
module.exports = function(source){
const content = doSomething2JsString(source);
// 如果loader配置了options对象,那么this.query将指向options
const options = this.query
this.fallback(null,content) //异步
return content; //同步
}
自定义Plugin,需要遵循的规范是:插件必须是一个函数或是包含apply方法的对象,这样才能访问compiler实例
class MyPlugin{
//Webpack会调用MyPlugin实例的apply方法给插件实例传入compiler对象
apply(compiler){
// 找到合适的事件钩子,实现自己的插件
compiler.hooks.emit.tap('MyPlugin',compilation=>{
//do something
})
}
}
5. CSS如何声明变量 【CSS】
不管前方的路有多苦,只要走的方向正确,不管多么崎岖不平,都比站在原地更接近幸福。
2022-10-13
1. Jest常用的expect方法有哪些? 【Jest】
参考答案
- expect(a).toBe(b)
- expect(a).toEqual(b)
- expect(a).not.toBe(b)
- expect(a).toBeNull(b)
- expect(a).toBeUndefined()
- expect(a).toBeTruthy()
- expect(a).toBeFalsy()
- expect(a).toContain(b)
2. 微信小程序的自动化测试流程步骤 【miniProgram】
参考答案
小程序官方的`Automator`模块,提供了启动及连接开发者工具的方法。
通过connect方法连接到开发工具后,通过 miniProgram
、Page
、Element
三个模块进行自动化测试。
3. rgba和opacity的透明效果有什么不同?【CSS】
参考答案
- 定义
- opacity:取值0-1,0表示完全透明,1表示完全不透明;
- rgba:R表示红色,G表示绿色,B表示蓝色,A表示透明度,取值0-1,0表示完全透明,1表示完全不透明;
- 区别:
- opacity作用于元素以及元素内所有内容.
- rgba()只作用于元素的颜色或者背景图;
即opacity会继承父元素的opacity属性,而RGBA设置的元素的后代元素不会继承其属性。
4. js中的BOM和DOM有什么区别?【JS】
参考答案
javascript是由三部分构成,ECMAScript,DOM和BOM,根据宿主(浏览器)的不同,具体的表现形式也不尽相同
# BOM是浏览器对象模型 Browser Object Model
- BOM和浏览器关系密切。是浏览器的内置脚本语言。浏览器的很多东西可以通过JavaScript控制的,例如打开新窗口、打开新选项卡(标签页)、关闭页面,把网页设为主页,或加入收藏夹,等等
- BOM由于没有标准,不同的浏览器实现同一功能,可以需要不同的实现方式。对于上面说的功能,不同的浏览器的实现功能所需要的JavaScript代码可能不相同。
- 常用BOM对象:window、Screen、Cookie、XMLHttpRequest、Storage、History、Location、IndexDB、WebWorker等
# DOM是文档对象模型 Document Object Model
- DOM和文档有关,这里的文档指的是网页,也就是HTML文档。网页是由服务器发送给客户端浏览器的,无论用什么浏览器,接收到的HTML都是一样的,所以DOM和浏览器无关,它关注的是网页本身的内容。由于和浏览器关系不大,所以标准就好定了。
- DOM是W3C的标准.
- DOM的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。
5. bind,apply,call三者的区别 【JS】
参考答案
- 首先,bind,call,apply的作用都是用来改变this指向的。
- apply方法接收两个参数,第一个参数是this的指向,第二个参数是函数接收的参数,已数组形式传入,且当第一个参数为null、undefined的时候,this默认指向window对象
- call方法接收的第一个参数也是this的指向,后面传入的是一个参数列表,其他与apply相同。
- bind和call方法相似,知识它改变this的指向后不会立即执行,而是返回一个永久改变this指向的函数。
人们想象自己是什么样子,那他们往往就是什么样子,他们终会变成自己所想的那样。
2022-10-12
1. git cherry-pick的使用 【Git】
参考答案
git cherry-pick的作用是从一个分支合并部分代码到另一个分支。
语法: git cherry-pick feature | <commitHash>
- 该命令将指定提交的(分支[最新提交内容] or commitHash),应用与当前分支,会在当前分支产生一个新的提交。
- 转移多个提交
git cherry-pick <HashA> <HashB>
,会在当前分支生成两个对应的新提交 - 转移一系列提交
git cherry-pick A..B
不包含 hashA
- 转移一系列提交
git cherry-pick A^..B
包含 hashA
- 相关配置项等详细内容 (opens new window)
2. 微信小程序如何区分体验版本、开发版本、正式版本 【miniProgram】
参考答案
使用 __wxConfig.envVersion 区分
- envVersion: 'develop', //开发版
- envVersion: 'trial', //体验版
- envVersion: 'release', //正式版
3. Vue中的nextTick原理 【Vue】
参考答案
# 作用
使用 Vue.nextTick()是为了可以获取更新后的 DOM 。
触发时机:在同一事件循环中的数据变化后,DOM 完成更新,立即执行 Vue.nextTick()的回调。
# 示例
- Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。
- 简单说就是,Vue 中的数据修改,并不是马上更新视图,而是等到同一时间循环中的所有变化完成之后,再进行统一的视图更新。
// 改变数据
vm.name = 'liugezhou'
console.log(vm.$el.textContent) // 不会得到liugezhou
Vue.nextTick(function(){
console.log(vm.$el.textContent) // 可以得到liugezhou
})
# 应用场景:
- 在 Vue 生命周期的 created()钩子函数进行的 DOM 操作一定要放在 Vue.nextTick()的回调函数中。 原因:是 created()钩子函数执行时 DOM 其实并未进行渲染。
- 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的 DOM 结构的时候,这个操作应该放在 Vue.nextTick()的回调函数中。 原因:Vue 异步执行 DOM 更新,只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变,如果同一个 watcher 被多次触发,只会被推入到队列中一次。
4. 如何判断一个对象是不是空对象?【JS】
参考答案
- JSON.stringify(JSON.parse(obj)) === '{}'
- Object.keys(obj).length === 0
5. 如何实现单行/多行文本溢出的省略样式? 【CSS】
参考答案
- 单行文本溢出
.p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
- 多行文本溢出
// 基于行数截断
.p {
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
}
// 基于高度截断
.demo {
position: relative;
line-height: 20px;
height: 40px;
overflow: hidden;
}
.demo::after {
content: '...';
position: absolute;
bottom: 0;
right: 0;
padding: 0 20px 0 10px;
}
我们曾经那么好,现在却连声问候,都怕是打扰。
2022-10-11
1. Vue3.0 里为什么要用 Proxy API 替代 defineProperty API? 【Vue】
参考答案
响应式优化。
- defineProperty API 的局限性最大原因是它只能针对单例属性做监听。 Vue2.x 中的响应式实现正是基于 defineProperty 中的 descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。 这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因,在 Vue 中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到 setter监听的,这是 defineProperty 的局限性。
- Proxy API 的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作, 这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。 Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
- 响应式是惰性的 在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗。 在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗。
2. git stash的用法 【Git】
参考答案
- 把未提交的修改(暂存和非暂存)保存起来
git stash save "test-cmd-stash" -u[存放未跟踪的文件] - 查看现有stash
git stash list - 查看指定stash的修改
git stash show [stash@{1}-不指定显示最新的] [-u 显示未跟踪文件] - 恢复之前的进度继续开发新功能 git stash pop [stash@{1}]
- 移除stash
git stash drop [stash_id(不指定删除最新的)] - 删除所有stash
git stash clear
3. item2 (终端) 常用的快捷键记录
参考答案
描述 | 命令 |
---|---|
新建标签 | command + t |
切换标签 | command + 数字 |
切换全屏 | command + enter |
垂直分屏 | command + d |
删除文本到末尾 | ctrl + k |
清除当前行 | ctrl + u |
清除当前屏幕 | ctrl + l |
到行首 | ctrl + a |
到行尾 | ctrl + e |
本地拷贝文件到服务器 | scp /Users/opload.js root@x.x.x.x:/data/ |
多级目录创建 | mkdir -p dir/dir1/dir2 |
文件拷贝 | cp -r /test/demo.js /data/demo.js |
文件移动 | mv /root/jar/demo.jar /data/ |
查看当前文件下所有路径 | find . |
解压文件 | tar -zxvf test.tar.zip -C /data/demo |
连接服务器 | ssh -p 22 root@ip_address |
系统信息 | uname -a |
本地地址 | ifconfig |
查看服务器端口占用 | netstat -tunpl |
4. 新建正则实例的两种方式 【Reg】
参考答案
- let regex = /xyz/;
- let regex = new RegExp('xyz','i')
5. 浏览器对象location.reload()参数作用 【BOM】
参考答案
location.reload():传入true,则重新加载本页面且scrollTop为0,传为false,则会回到当前位置。
平庸将你的心灵烘干到没有一丝水分,然后荣光才会拨动你心灵最深处的弦。
2022-10-10
1. Webpack中的sourceMap配置? 【Webpack】
参考答案
- 项目打包后,如果关闭 sourceMap 的配置,在浏览器打开项目后,看到的 js 代码为打包后的代码,不利于查找代码错误。
- sourceMap 是一个映射关系,他可以知道在 dist 打包后的 main.js 错误的代码对应在未经打包的代码的位置。
配置项为:
- devtool:'source-map'---会在 dist 目录下生成一个.map 的映射文件。
- 如果为'inline-source-map',则不会生成.map 文件,直接在原 main.js 文见中添加注释以映射(位置在底部)。
- 如果为'cheap-inline-source-map' :与 inline 不同,只告诉是哪行代码出错,效率会高一些。
- 如果为"cheap-module-source-map':不管是业务代码,但是依赖的第三方模块,都会显示出出错的地方。
- eval 是打包效率最高的方式。
- 如果是开发环境,建议使用“cheap-module-eval-source-map'这种方式。如果是生产环境,一般不用设置 devtool 的配置。如果要配置,推荐使用"cheap-module-source-map"。
2.JS编译解析原理以及AST的理解 【JS】
参考答案
JS的编译原理简单说就是先对源代码进行分词(分解)转换成一个个有意义的代码块,然后将这些有意义的代码块生成抽象语法树AST,最后对AST进行操作、解析成可执行代码进行执行。
- 首先这个AST也就是抽象语法树,是 Abstract Syntax Tree的缩写。
- AST生成的主要就是两个步骤:词法分析和语法分析。
- 词法分析:就是读取源代码,安装预定的规则(比如遇到空格、括号、换行等)将代码合成一个个的标识token。
- 语法分析:就是将词法分析出来的数组转换成树的表达形式,并同时验证代码语法是否有误。
- 然后这个时候就生成一颗抽象语法树,它定义了代码的结构。通过操纵这颗树,我们可以精确定位到声明语句、赋值语句、运算语句等等,实现对代码的分析、优化、变更等操作。
很多工具和库的核心都是AST,像webpack、lint、babel等,一般都是分三个阶段运行代码:解析(parsing),转译(transforming),生成(generation)
3.node是单线程,为什么能处理高并发 【JS】
参考答案
事件驱动。
- 每个Node.js进程只有一个主线程在执行程序代码,行成一个执行栈
- 主线程之外还维护了一个"事件队列"(Event Queue),当用户的网络请求或者其他异步操作到来时,node都会放到事件队列中去,此时不会立即执行这个异步任务,代码也不会阻塞,会继续往下走,直到主线程代码执行完毕。
- 主线程代码执行完毕后,通过事件循环机制(Event Loop),到事件队列的开头取出第一个事件去执行,执行完毕后主线程不断检查事件队列中是否有未执行事件,若有继续执行,直到事件队列中所有事件执行完毕。
- 主线程不断重复上面的第三步
Node之所以单线程可以处理高并发的原因,在于libuv层的事件循环机制,和底层线程池的实现,在事件循环机制上,新版本的node和浏览器类似。
4. Promise和async await是解决什么问题的,为什么存在两种方式?【JS】
参考答案
- 首先,Promise的出现是为了解决异步产生的回调地狱,使得开发人员用新的方式来编写程序。
- 而Promise出现引出的新问题是如果有多个Promise要执行,虽然Promise.all可以解决,但是如果存在Promise先后的执行顺序,Promise就不能很好的解决了。
- 然后 async await出现,允许异步程序用同步代码的方式写程序,也就是说async await解决了Promise产生的一些问题,且是建立在Promise的基础上实现的,返回的仍然是一个Promise。
5. TypeScript 如何设计 Class 的声明? 【TS】
参考答案
在声明类的时候,一般类中都会包含:构造函数、对构造函数中的属性进行类型声明、类中的方法。
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string{
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
Life was a box of chocolates, you never know what you're gonna get.
2022-10-09
1. 浏览器在生成页面的时候,会生成那两颗树?【Web】
参考答案
构造两棵树,DOM 树和 CSSOM 规则树, 当浏览器接收到服务器相应来的 HTML 文档后,会遍历文档节点,生成 DOM 树, CSSOM 规则树由浏览器解析 CSS 文件生成。
2. csrf 和 xss 的网络攻击及防范 【Web】
参考答案
CSRF:跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送了恶意请求,比如用户登录了一个网站后,立刻在另一个tab页面访问量攻击者用来制造攻击的网站,这个网站要求访问刚刚登陆的网站,并发送了一个恶意请求,这时候CSRF 就产生了。
比如这个制造攻击的网站使用一张图片,但是这种图片的链接却是可以修改数据库的,这时候攻击者就可以以用户的名义操作这个数据库,防御方式的话:使用验证码,检查 https 头部的 refer,使用 token。
XSS:跨站脚本攻击,是说攻击者通过注入恶意的脚本,在用户浏览网页的时候进行攻击,比如获取 cookie,或者其他用户身份信息,可以分为存储型和反射型,存储型是攻击者输入一些数据并且存储到了数据库中,其他浏览者看到的时候进行攻击,反射型的话不存储在数据库中,往往表现为将攻击代码放在 url 地址的请求参数中,防御的话为 cookie 设置 httpOnly 属性,对用户的输入进行检查,进行特殊字符过滤。
3. cookie 和 session 的区别 【JS】
参考答案
- cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
- cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺 骗 考虑到安全应当使用 session。
- session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务 器的性能 考虑到减轻服务器性能方面,应当使用 COOKIE。
- 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
4. overflow 的原理 【CSS】
参考答案
要讲清楚这个解决方案的原理,首先需要了解块格式化上下文
A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with each other.
翻译过来就是:块格式化上下文是 CSS 可视化渲染的一部分,它是一块区域,规定了内部块盒 的渲染方式,以及浮动相互之间的影响关系
当元素设置了 overflow 样式且值部位 visible 时,该元素就构建了一个 BFC,BFC 在计算高度时,内部浮动元素的高度也要计算在内,也就是说技术 BFC 区域内只有一个 浮动元素,BFC 的高度也不会发生塌缩,所以达到了清除浮动的目的。
5. box-sizing 的语法和基本用处 【CSS】
参考答案
box-sizing 规定两个并排的带边框的框,语法为 box-sizing:content-box/border-box/inherit
- content-box:宽度和高度分别应用到元素的内容框,在宽度和高度之外绘制元素的内边距和边框
- border-box:为元素设定的宽度和高度决定了元素的边框盒,
- inherit:继承父元素的 box-sizing
你从自己的一次失败中学到的东西,比阅读一千个成功故事学到的更多。
2022-10-08
1. transform与transition属性都有哪些 【CSS】
参考答案
transform
transform 允许缩放、旋转、平移、倾斜等。
- matrix(a1,a2,a3,a4,a5,a6) 定义 2D 转换
- translate(x,y) x 轴与 y 轴的 2D 平移转换
- scale(x,y) x 轴与 y 轴缩放的 2D 转换
- rotate(angle) x 轴与 y 轴 2D 旋转角度 转换
- skew(x-angle,y-angle) x 轴与 y 轴的 2D 倾斜转换
transition
- transition 属性是
transition-property
、transition-duration
、transition-timing-function
、transition-delay
四个属性的简写属性。
transition-property
:用来设置元素中参与过渡的属性名称 ,语法格式:transition-property:none | all | property
- none:没有属性参与过渡
- all:所有属性参与过渡
- property:CSS 属性过渡列表,多个属性使用逗号分隔
transition-duration
:用来设置过渡需要花费的时间 语法格式:transition-duration:time
多个属性之间可用逗号进行分割:transition-duration:1s,2s,3s;
transition-timing-function
:用来设置过渡动画的类型
- linear:匀速
- ease:慢到快再到慢
- ease-in:慢速开始过渡
- ease-out:慢速结束过渡
transition-delay
: 设置过渡效果何时开始,即等待的时间
2. animation的属性 【CSS】
参考答案
@keyframes
规则
@keyframes animationName{
from {}
percentage{}
to{}
}
animationName
:动画名称from
:定义动画的开头 0%percentage
:动画各个阶段,为百分比值,可添加多个to
:动画结尾,100%
- 动画应用
通过
1
创建好动画后,需要将动画应用指定到HTML元素,CSS提供的动画属性有:
animation-name
:设置需要绑定到元素的动画名称animation-duration
:动画开始到完成所花费的时间animation-timing-function
:动画速度曲线,默认为easeanimation-fill-mode
:设置当前动画不播放时的状态(forwards为最后一个关键帧样式,backwards为第一个关键中样式,both为两者)animation-delay
:动画开始执行的延迟时间animation-iteration-count
:设置动画的播放次数,infinite表示无限次播放,默认值为1animation-play-state
:设置动画是正在运行还是暂停,默认是runninganimation
:动画的所有属性
3. 什么是原生ESM? 【JS】
参考答案
- JavaScript模块,即提供一种将 JavaScript 程序拆分为可按需导入的单独模块的机制
- 最新的浏览器开始原生支持模块功能了-- 这会是一个好事情 — 浏览器能够最优化加载模块,使它比使用库更有效率:使用库通常需要做额外的客户端处理。
- 关键词:
import
export
- 根据MDN JS ESM (opens new window)体验。
4. Vite的解决思路是基于什么?
参考答案
- Vite是基于
浏览器开始原生支持ES模块,且越来越多的JS工具使用编译性语言编写
- Vite针对缓慢的服务器启动,解决思路是:
基于打包器方式的启动是必须优先抓取并构建整个应用,然后才能提供服务,而Vite是在一开始将应用中的模块分为依赖和源码两项,改进开发服务器启动慢的问题
- 依赖使用esbuild预构建依赖。
- 源码以原生ESM方式提供(浏览器接管了打包程序的部分工作)。
- 在 Vite 中,HMR 是在原生 ESM 上执行的。
5. Webpack的tree-shaking是什么,需要注意哪些问题,如何配置?
参考答案
- 一个js文件中有a和b两个方法,只用到了a方法,b方法没有用到,tree-shaking就是解决打包的时候不去打包没用到的b方法。
- Tree-shaking只支持ES Module(import,export),不支持require
- 生产环境Tree-shaking默认配置好了,不需要对optimization配置,但仍需要对package.json中的sideEffects配置。
- 开发环境默认没有配置tree-shaking,需要在webpack.config.js配置文件中添加
optimization:{usedExports:true}
,如果引入第三方资源,需要在package.json
中配置sideEffects:false