首页

2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(三)

本文是2022年来前端开发人员自求职过程中最新面试题系列的第三篇,主要包括函数组件和类组件、for in和for of、react与vue、react更新机制、BFC及其优缺点、SPA单页面、盒模型、前端登录流程、Http与Https协议区别、vue中购物车实现原理、常见的git状态。

下面开始挨个过一遍。

51、说一下for…in 和 for…of的区别?

for...of遍历获取的是对象的键值, for...in获取的是对象的键名;
for...in会遍历对象的整个原型链, 性能非常差不推荐使用,而for...of只遍历当前对象不会遍历原型链;
对于数组的遍历,for...in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for...of只返回数组的下标对应的属性值;
总结:for...in循环主要是为了遍历对象而生,不适用遍历数组; for....of循环可以用来遍历数组、类数组对象、字符串、Set、Map以及Generator对象
复制代码

52、说一下类组件和函数组件的区别?

1. 语法上的区别:

函数式组件是一个纯函数,它是需要接受props参数并且返回一个React元素就可以了。类组件是需要继承React.Component的,而且class组件需要创建render并且返回React元素,语法上来讲更复杂。

2. 调用方式

函数式组件可以直接调用,返回一个新的React元素;类组件在调用时是需要创建一个实例的,然后通过调用实例里的render方法来返回一个React元素。

3. 状态管理

函数式组件没有状态管理,类组件有状态管理。

4. 使用场景

类组件没有具体的要求。函数式组件一般是用在大型项目中来分割大组件(函数式组件不用创建实例,所有更高效),一般情况下能用函数式组件就不用类组件,提升效率。
复制代码

53、说一下react的更新机制

54、说一下redux 里面有什么

55、说一下react和vue框架的区别

56、说一下proxy  它有什么优点

57、说一下vue3.0你了解多少?

 <!-- 响应式原理的改变 Vue3.x 使用Proxy取代 Vue2.x 版本的Object.defineProperty -->
 <!-- 组件选项声明方式Vue3.x 使用Composition API setup 是Vue3.x新增的一个选项,他
    是组件内使用Composition API 的入口 -->
 <!-- 模板语法变化slot具名插槽语法 自定义指令 v-model 升级 -->
 <!-- 其它方面的更改Suspense支持Fragment(多个根节点) 和Protal (在dom其他部分渲染组建内容)组件
     针对一些特殊的场景做了处理。基于treeshaking优化,提供了更多的内置功能。 -->
复制代码

58、说一下bfc bfc有什么优缺点

59、说一下你对盒模型的理解?

CSS3中的盒模型有以下两种:标准盒模型、IE盒模型
盒模型都是由四个部分组成的,分别是margin、border、padding和content
标准盒模型和IE盒模型的区别在于设置width和height时, 所对应的范围不同
1、标准盒模型的width和height属性的范围只包含了content
2、IE盒模型的width和height属性的范围包含了border、padding和content
可以通过修改元素的box-sizing属性来改变元素的盒模型;
1、box-sizing:content-box表示标准盒模型(默认值)
2、box-sizing:border-box表示IE盒模型(怪异盒模型)
复制代码

60、说一下SPA单页面有什么优缺点?

优点:

1.体验好,不刷新,减少 请求  数据ajax异步获取 页面流程;

2.前后端分离

3.减轻服务端压力

4.共用一套后端程序代码,适配多端

缺点:

1.首屏加载过慢;

2.SEO 不利于搜索引擎抓取
复制代码

61、说一下前端登录的流程?

初次登录的时候,前端调后调的登录接口,发送用户名和密码,后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token,和一个用户信息的值,前端拿到token,将token储存到Vuex中,然后从Vuex中把token的值存入浏览器Cookies中。把用户信息存到Vuex然后再存储到LocalStroage中,然后跳转到下一个页面,根据后端接口的要求,只要不登录就不能访问的页面需要在前端每次跳转页面师判断Cookies中是否有token,没有就跳转到登录页,有就跳转到相应的页面,我们应该再每次发送post/get请求的时候应该加入token,常用方法再项目utils/service.js中添加全局拦截器,将token的值放入请求头中 后端判断请求头中有无token,有token,就拿到token并验证token是否过期,在这里过期会返回无效的token然后有个跳回登录页面重新登录并且清除本地用户的信息

62、说一下前端权限管理怎么实现

63、说一下购物车的逻辑?

//vue中购物车逻辑的实现
1. 购物车信息用一个数组来存储,数组中保存对象,对象中有id和count属性

2. 在vuex中state中添加一个数据 cartList 用来保存这个数组

3. 由于商品详情页需要用到加入购物车功能,所以我们需要提供一个mutation, 用来将购物车信息加入 cartList中

4. 加入购物车信息的时候,遵照如下规则: 如果购物车中已经有了该商品信息,则数量累加,如果没有该商品信息,则新增一个对象

5. 在商品详情页,点击加入购物车按钮的时候,调用vuex提供的addToCart这个mutation将当前的商品信息 (id count)传给addTocart  this.$store.commit("addToCart", {id:  , count:})

// js中购物车逻辑的实现
1.商品页点击“加入购物车”按钮,触发事件

2.事件调用购物车“增加商品”的Js程序(函数、对象方法)

3.向Js程序传递传递“商品id”、“商品数量”等数据

4.存储“商品id”、“商品数量”到浏览器的localStorage中

**展示购物车中的商品******

1.打开购物车页面

2.从localStorage中取出“商品Id”、“商品数量”等信息。

3.调用服务器端“获得商品详情”的接口得到购物车中的商品信息(参数为商品Id)

4.将获得的商品信息显示在购物车页面。

**完成购物车中商品的购买******

1.用户对购物车中的商品完成购买流程,产生购物订单

2.清除localStorage中存储的已经购买的商品信息

备注1:购物车中商品存储的数据除了“商品id”、“商品数量”之外,根据产品要求还可以有其他的信息,例如完整的商品详情(这样就不用掉服务器接口获得详情了)、购物车商品的过期时间,超过时间的购物车商品在下次打开网站或者购物车页面时被清除。

备注2:购物车商品除了存储在localStorage中,根据产品的需求不同,也可以存储在sessionStorage、cookie、session中,或者直接向服务器接口发起请求存储在服务器上。何种情况使用哪种方式存储、有啥区别请自己分析。
复制代码

64、说一下HTTP和HTTPS协议的区别?

1、HTTPS协议需要CA证书,费用较高;而HTTP协议不需要
2、HTTP协议是超文本传输协议,信息是明文传输的,HTTPS则是具有安全性的SSL加密传输协议;
3、使用不同的连接方式,端口也不同,HTTP协议端口是80,HTTPS协议端口是443;
4、HTTP协议连接很简单,是无状态的;HTTPS协议是具有SSL和HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP更加安全
复制代码
65、说一下常见的HTTP状态码?说一下状态码是302和304是什么意思?你在项目中出现过么?你是怎么解决的?
    <!-- 状态码:由3位数字组成,第一个数字定义了响应的类别 -->
    <!-- 1xx:指示消息,表示请求已接收,继续处理 -->
    <!-- 2xx:成功,表示请求已被成功接收,处理 -->
    <!-- 200 OK:客户端请求成功
         204 No Content:无内容。服务器成功处理,但未返回内容。一般用在只是客户端向服务器发送信息,而服务器不用向客户端返回什么信息的情况。不会刷新页面。
         206 Partial Content:服务器已经完成了部分GET请求(客户端进行了范围请求)。响应报文中包含Content-Range指定范围的实体内容
 -->
    <!-- 3xx 重定向 -->
    <!-- 301 Moved Permanently:永久重定向,表示请求的资源已经永久的搬到了其他位置。
         302 Found:临时重定向,表示请求的资源临时搬到了其他位置
         303 See Other:临时重定向,应使用GET定向获取请求资源。303功能与302一样,区别只是303明确客户端应该使用GET访问
         307 Temporary Redirect:临时重定向,和302有着相同含义。POST不会变成GET
         304 Not Modified:表示客户端发送附带条件的请求(GET方法请求报文中的IF…)时,条件不满足。返回304时,不包含任何响应主体。虽然304被划分在3XX,但和重定向一毛钱关系都没有
 -->
    <!-- 4xx:客户端错误 -->
    <!-- 400 Bad Request:客户端请求有语法错误,服务器无法理解。
         401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
         403 Forbidden:服务器收到请求,但是拒绝提供服务
         404 Not Found:请求资源不存在。比如,输入了错误的url
         415 Unsupported media type:不支持的媒体类型
 -->
    <!-- 5xx:服务器端错误,服务器未能实现合法的请求。 -->
    <!-- 500 Internal Server Error:服务器发生不可预期的错误。
         503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,
 -->
复制代码

66、说一下常见的git操作

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下来

//  我是cv的自取吧

限于篇幅,有些前端面试题没有提供答案,如果有答案的可以评论区贴出来共勉。

本篇标志本系列完结,这些都是2022年开年以来前端工程师在实际找工作面试或者笔试遇到的技术问题,也是用人单位最看重的你必须过硬的吃饭的家伙,大家务必牢牢掌握,争取早日拿到offer。

如有新的题目也欢迎留言分享,让更多的人看见。

第一篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(一)

第二篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(二)

致敬作者:villay
链接:juejin.cn/post/7073869980411887652
来源:稀土掘金

2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(二)

本文是2022年来前端开发人员自求职过程中最新面试题系列的第二篇,主要包括Vuex、Loader和Plugin、浏览器浏览URL时的工作原理、UDP-TCP、Vue生命周期和钩子以及父子组件、项目性能优化方式、watch、组件之间值传递、布局有关的水平垂直、浏览器性能监控、diff、防抖和节流、虚拟列表、内存泄漏、常用检测数据类型的方式、三个切割函数slice splice split的区别、数组相关的数组转换和去重、JSON。

下面开始。

14、Vuex有哪些基本属性?为什么 Vuex 的 mutation 中不能做异步操作?

有五种,分别是 State、 Getter、Mutation 、Action、 Module
1、state => 基本数据(数据源存放地)
2、getters => 从基本数据派生出来的数据
3、mutations => 提交更改数据的方法,同步
4、actions => 像一个装饰器,包裹mutations,使之可以异步。
5、modules => 模块化Vuex

1、Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解我们的应用。
2、每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。
复制代码

15、Loader和Plugin 有什么区别

Loader:直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到`loader`。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。 Plugin:直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

16、在地址栏里输入一个地址回车会发生哪些事情

1、解析URL:首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。
2、缓存判断:浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。
3、DNS解析: 下一步首先需要获取的是输入的 URL 中的域名的 IP 地址,首先会判断本地是否有该域名的 IP 地址的缓存,如果有则使用,如果没有则向本地 DNS 服务器发起请求。本地 DNS 服务器也会先检查是否存在缓存,如果没有就会先向根域名服务器发起请求,获得负责的顶级域名服务器的地址后,再向顶级域名服务器请求,然后获得负责的权威域名服务器的地址后,再向权威域名服务器发起请求,最终获得域名的 IP 地址后,本地 DNS 服务器再将这个 IP 地址返回给请求的用户。用户向本地 DNS 服务器发起请求属于递归请求,本地 DNS 服务器向各级域名服务器发起请求属于迭代请求。
4、获取MAC地址: 当浏览器得到 IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。通过将 IP 地址与本机的子网掩码相与,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。
5、TCP三次握手: 下面是 TCP 建立连接的三次握手的过程,首先客户端向服务器发送一个 SYN 连接请求报文段和一个随机序号,服务端接收到请求后向客户端发送一个 SYN ACK报文段,确认连接请求,并且也向客户端发送一个随机序号。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。
6、HTTPS握手: 如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供一个前面所有内容的 hash 值供服务器端检验。服务器端接收后,使用自己的私钥对数据解密,同时向客户端发送一个前面所有内容的 hash 值供客户端检验。这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输。
7、返回数据: 当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。
8、页面渲染: 浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。
9、TCP四次挥手: 最后一步是 TCP 断开连接的四次挥手过程。若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
复制代码

17、UDP和TCP有什么区别

TCP和UDP的区别.png

18、项目中常用的性能优化方式有哪些?

太多了,自己整理吧

19、怎么解决跨域问题的,你是怎么配置的

20、计算属性和watch有什么区别?以及它们的运用场景?

// 区别
  computed 计算属性:依赖其它属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值。
  watch 侦听器:更多的是观察的作用,无缓存性,类似与某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作
//运用场景
  当需要进行数值计算,并且依赖与其它数据时,应该使用computed,因为可以利用computed的缓存属性,避免每次获取值时都要重新计算。
  当需要在数据变化时执行异步或开销较大的操作时,应该使用watch,使用watch选项允许执行异步操作(访问一个API),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
复制代码

21、Vue的生命周期是什么 每个钩子里面具体做了什么事情

Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。
1、beforeCreate(创建前) :数据观测和初始化事件还未开始,此时 data 的响应式追踪、event/watcher 都还没有被设置,也就是说不能访问到data、computed、watch、methods上的方法和数据。
2、created(创建后) :实例创建完成,实例上配置的 options 包括 data、computed、watch、methods 等都配置完成,但是此时渲染得节点还未挂载到 DOM,所以不能访问到 `$el` 属性。
3、beforeMount(挂载前) :在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。此时还没有挂载html到页面上。
4、mounted(挂载后) :在el被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html 页面中。此过程中进行ajax交互。
5、beforeUpdate(更新前) :响应式数据更新时调用,此时虽然响应式数据更新了,但是对应的真实 DOM 还没有被渲染。
6、updated(更新后):在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。此时 DOM 已经根据响应式数据的变化更新了。调用时,组件 DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
7、beforeDestroy(销毁前) :实例销毁之前调用。这一步,实例仍然完全可用,`this` 仍能获取到实例。
8、destroyed(销毁后) :实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务端渲染期间不被调用。
另外还有 `keep-alive` 独有的生命周期,分别为 `activated` 和 `deactivated` 。用 `keep-alive` 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 `deactivated` 钩子函数,命中缓存渲染后会执行 `activated` 钩子函数。
复制代码

22、组件之间的传值有几种方式

1、父传子
2、子传父
3、eventbus
4、ref/$refs
5、$parent/$children
6、$attrs/$listeners
7、依赖注入(provide/inject)
复制代码

23、Eventbus具体是怎么实现的

24、父组件到子组件更新的方式是什么样的

25、$nexttick 是干嘛的,你一般拿它做什么

26、Keepalive 是什么,里面有哪些钩子

27、插槽是什么 怎么使用的

28、Es6常见的语法你知道哪一些

29、自定义指令你是怎么用的

30、重绘和重排

31、常见的水平垂直方式有几种?

//利用绝对定位,先将元素的左上角通过 top:50%和 left:50%定位到页面的中心,然后再通过 translate 来调整元素的中心点到页面的中心。该方法需要考虑浏览器兼容问题。
.parent {
    position: relative;
}

.child {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}
//利用绝对定位,设置四个方向的值都为 0,并将 margin 设置为 auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况:
.parent {
    position: relative;
}

.child {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
//利用绝对定位,先将元素的左上角通过 top:50%和 left:50%定位到页面的中心,然后再通过 margin 负值来调整元素的中心点到页面的中心。该方法适用于盒子宽高已知的情况
.parent {
    position: relative;
}

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;     /* 自身 height 的一半 */
    margin-left: -50px;    /* 自身 width 的一半 */
}
//使用 flex 布局,通过 align-items:center 和 justify-content:center 设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。该方法要**考虑兼容的问题**,该方法在移动端用的较多:
.parent {
    display: flex;
    justify-content:center;
    align-items:center;
}
//另外,如果父元素设置了flex布局,只需要给子元素加上`margin:auto;`就可以实现垂直居中布局
.parent{
    display:flex;
}
.child{
    margin: auto;
}
复制代码

32、标准盒模型和怪异盒模型

33、Flex常见的属性  flex:1代表什么

34、Rem你是怎么做适配的

35、媒体查询是什么

36、首屏性能优化你是怎么做的

37、怎么解决白屏问题

1、加loading
2、骨架屏

38、浏览器的性能监控你是怎么做的

戳右边链接blog.csdn.net/qq_29438877…

39、Diff算法是什么  :key = index 为什么不常用数组的下标作为index  加了它有什么好处

40、虚拟列表你是怎么实现的

41、说一下防抖和节流

42、哪些情况会导致内存泄漏

1、意外的全局变量:由于使用未声明的变量,而意外的创建了一个全局变量,而使这个变量一直留在内存中无法被回收
2、被遗忘的计时器或回调函数:设置了 setInterval 定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收。
3、脱离 DOM 的引用:获取一个 DOM 元素的引用,而后面这个元素被删除,由于一直保留了对这个元素的引用,所以它也无法被回收。
4、闭包:不合理的使用闭包,从而导致某些变量一直被留在内存当中。
复制代码

43、Vue的父子组件生命周期钩子函数执行顺序?

<!-- 加载渲染过程 -->
    <!-- 父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created ->
    子beforeMount -> 子mounted -> 父mounted -->
    <!-- 子组件更新过程 -->
    <!-- 父beforeUpdate -> 子beforeUpdate -> 子updaed -> 父updated -->
    <!-- 父组件跟新过程 -->
    <!-- 父beforeUpdate -> 父updated -->
    <!-- 销毁过程 -->
    <!-- 父beforeDestroy -> 子beforeDestroy -> 子destroyed ->父destroyed -->
复制代码

44、说一下常见的检测数据类型的几种方式?

typeof  其中数组、对象、null都会被判断为Object,其他判断都正确

instanceof 只能判断引用数据类型,不能判断基本数据类型

constructor 它有2个作用 一是判断数据的类型,二是对象实例通过constructor对象访问它的构造函数。需要注意的事情是如果创建一个对象来改变它的原型,constructor就不能来判断数据类型了

Object.prototype.toString.call()
复制代码

45、说一下data为什么是一个函数而不是一个对象?

JavaScript中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。而在Vue中,我们更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。

46、说一下slice splice split 的区别?

// slice(start,[end])
// slice(start,[end])方法:该方法是对数组进行部分截取,该方法返回一个新数组
// 参数start是截取的开始数组索引,end参数等于你要取的最后一个字符的位置值加上1(可选)。
// 包含了源函数从start到 end 所指定的元素,但是不包括end元素,比如a.slice(0,3);
// 如果出现负数就把负数与长度相加后再划分。
// slice中的负数的绝对值若大于数组长度就会显示所有数组
// 若参数只有一个,并且参数大于length,则为空。
// 如果结束位置小于起始位置,则返回空数组
// 返回的个数是end-start的个数
// 不会改变原数组
var arr = [1,2,3,4,5,6]
/*console.log(arr.slice(3))//[4,5,6] 从下标为0的到3,截取3之后的数
console.log(arr.slice(0,3))//[1,2,3] 从下标为0的地方截取到下标为3之前的数
console.log(arr.slice(0,-2))//[1,2,3,4]
console.log(arr.slice(-4,4))//[3,4]
console.log(arr.slice(-7))//[1,2,3,4,5,6]
console.log(arr.slice(-3,-3))// []
console.log(arr.slice(8))//[]*/
// 个人总结:slice的参数如果是正数就从左往右数,如果是负数的话就从右往左边数,
// 截取的数组与数的方向一致,如果是2个参数则截取的是数的交集,没有交集则返回空数组 
// ps:slice也可以切割字符串,用法和数组一样,但要注意空格也算字符

// splice(start,deletecount,item)
// start:起始位置
// deletecount:删除位数
// item:替换的item
// 返回值为被删除的字符串
// 如果有额外的参数,那么item会插入到被移除元素的位置上。
// splice:移除,splice方法从array中移除一个或多个数组,并用新的item替换它们。
//举一个简单的例子 
var a=['a','b','c']; 
var b=a.splice(1,1,'e','f'); 
 console.log(a) //['a', 'e', 'f', 'c']
 console.log(b) //['b']

 var a = [1, 2, 3, 4, 5, 6];
//console.log("被删除的为:",a.splice(1, 1, 8, 9)); //被删除的为:2
// console.log("a数组元素:",a); //1,8,9,3,4,5,6

// console.log("被删除的为:", a.splice(0, 2)); //被删除的为:1,2
// console.log("a数组元素:", a) //3,4,5,6
console.log("被删除的为:", a.splice(1, 0, 2, 2)) //插入 第二个数为0,表示删除0个  
console.log("a数组元素:", a) //1,2,2,2,3,4,5,6

// split(字符串)
// string.split(separator,limit):split方法把这个string分割成片段来创建一个字符串数组。
// 可选参数limit可以限制被分割的片段数量。
// separator参数可以是一个字符串或一个正则表达式。
// 如果separator是一个空字符,会返回一个单字符的数组,不会改变原数组。
var a="0123456";  
var b=a.split("",3);  
console.log(b);//b=["0","1","2"]
// 注意:String.split() 执行的操作与 Array.join 执行的操作是相反的。
复制代码

47、说一下怎么把类数组转换为数组?

//通过call调用数组的slice方法来实现转换
Array.prototype.slice.call(arrayLike)

//通过call调用数组的splice方法来实现转换
Array.prototype.splice.call(arrayLike,0)

//通过apply调用数组的concat方法来实现转换
Array.prototype.concat.apply([],arrayLike)

//通过Array.from方法来实现转换
Array.from(arrayLike)
复制代码

48、说一下数组如何去重,你有几种方法?

let arr = [1,1,"1","1",true,true,"true",{},{},"{}",null,null,undefined,undefined]

// 方法1
let uniqueOne = Array.from(new Set(arr)) console.log(uniqueOne)

// 方法2
let uniqueTwo = arr => {
    let map = new Map(); //或者用空对象 let obj = {} 利用对象属性不能重复得特性
    let brr = []
    arr.forEach( item => {
        if(!map.has(item)) { //如果是对象得话就判断 !obj[item]
            map.set(item,true) //如果是对象得话就obj[item] =true 其他一样
            brr.push(item)
        }
    })
    return brr
}
console.log(uniqueTwo(arr))

//方法3
let uniqueThree = arr => {
    let brr = []
    arr.forEach(item => {
        // 使用indexOf 返回数组是否包含某个值 没有就返回-1 有就返回下标
        if(brr.indexOf(item) === -1) brr.push(item)
        // 或者使用includes 返回数组是否包含某个值 没有就返回false 有就返回true
        if(!brr.includes(item)) brr.push(item)
    })
    return brr
}
console.log(uniqueThree(arr))

//方法4
let uniqueFour = arr => {                                         
     // 使用 filter 返回符合条件的集合
    let brr = arr.filter((item,index) => {
        return arr.indexOf(item) === index
    })
    return brr
}
console.log(uniqueFour(arr))
复制代码

49、说一下怎么取出数组最多的一项?

// 我这里只是一个示例
const d = {};
let ary = ['赵', '钱', '孙', '孙', '李', '周', '李', '周', '周', '李'];
ary.forEach(k => !d[k] ? d[k] = 1 : d[k]++);
const result = Object.keys(d).sort((a, b) => d[b] - d[a]).filter((k, i, l) => d[k] === d[l[0]]);
console.log(result)
复制代码

50、说一下JSON.stringify有什么缺点?

1.如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式
2.如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;
3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
6、如果对象中存在循环引用的情况也无法正确实现深拷贝;

好,本篇就到这里,有些题目没有给出答案,能力有限或者太多亦或许我相信大家可以自己百度解决,但列出就是重点,务必要搞懂,没准面试就会有。

第一篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(一)

第三篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(三)

致敬作者:villay
链接:juejin.cn/post/7073869980411887652
来源:稀土掘金

2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(一)

求职找工作的金三银四已经过去了快一半,收疫情和整个大房间的影响,目前工作的竞争压力非常大。尤其对于人数众多的初级工程师来说,竞争尤为激烈,这里总结了2022年以来来自一线的各位求职者遇到的实际的前端面试和笔试题目,而且附带案例和代码,希望有助于大家查缺补漏,明确方向,提高自身竞争力,让自己脱颖而出,顺利拿到offer。

因为内容比较多,而且会不定期更新追加,所以暂时会分为三篇,本文是第一篇,主要包含,vue中的双向数据绑定原理、语法糖、哈希、浅拷贝和深拷贝、以及常问常新的原型和原型链、闭包、Promise、New、Set\Map、localStorage,sessionStorage,cookies区别、Vuex等,废话不多说,直接上题目和答案。

1、什么是原型什么是原型链?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function Person () {

    }
    var person  = new Person();
    person.name = 'Kevin';
    console.log(person.name) // Kevin

    // prototype
    function Person () {

    }
    Person.prototype.name = 'Kevin';
    var person1 = new Person();
    var person2 = new Person();
    console.log(person1.name)// Kevin
    console.log(person2.name)// Kevin

    // __proto__
    function Person () {

    }
    var person = new Person();
    console.log(person.__proto__ === Person.prototype) // true

    //constructor
    function Person() {

    }
    console.log(Person === Person.prototype.constructor) // true

    //综上所述
    function Person () {

    }
    var person = new Person()
    console.log(person.__proto__ == Person.prototype) // true
    console.log(Person.prototype.constructor == Person) // true
    //顺便学习一下ES5得方法,可以获得对象得原型
    console.log(Object.getPrototypeOf(person) === Person.prototype) // true

    //实例与原型
    function Person () {

    }
    Person.prototype.name = 'Kevin';
    var person = new Person();
    person.name = 'Daisy';
    console.log(person.name) // Daisy
    delete person.name;
    console.log(person.name) // Kevin

    //原型得原型
    var obj = new Object();
    obj.name = 'Kevin',
    console.log(obj.name) //Kevin

     //原型链
     console.log(Object.prototype.__proto__ === null) //true
     // null 表示"没用对象" 即该处不应该有值

     // 补充
     function Person() {

     }
     var person = new Person()
     console.log(person.constructor === Person) // true
     //当获取person.constructor时,其实person中并没有constructor属性,当不能读取到constructor属性时,会从person的原型
     //也就是Person.prototype中读取时,正好原型中有该属性,所以
     person.constructor === Person.prototype.constructor

     //__proto__
     //其次是__proto__,绝大部分浏览器都支持这个非标准的方法访问原型,然而它并不存在于Person.prototype中,实际上,它
     // 是来自与Object.prototype,与其说是一个属性,不如说是一个getter/setter,当使用obj.__proto__时,可以理解成返回了
     // Object.getPrototypeOf(obj)
     总结:
     
     1、当一个对象查找属性和方法时会从自身查找,如果查找不到则会通过__proto__指向被实例化的构造函数的prototype

     2、隐式原型也是一个对象,是指向我们构造函数的原型

     3、除了最顶层的Object对象没有__proto_,其他所有的对象都有__proto__,这是隐式原型

     4、隐式原型__proto__的作用是让对象通过它来一直往上查找属性或方法,直到找到最顶层的Object的__proto__属性,它的值是null,这个查找的过程就是原型链



</script>
</html>
复制代码

2、箭头函数和普通函数有什么区别?

(1)箭头函数比普通函数更加简洁
    如果没有参数,就直接写一个空括号即可
    如果只有一个参数,可以省去参数括号
    如果有多个参数,用逗号分割
    如果函数体的返回值只有一句,可以省略大括号
    如果函数体不需要返回值,且只有一句话,可以给这个语句前面加一个void关键字。最常用的就是调用一个函数:
    let fn = () => void doesNotReturn()
    
 (2) 箭头函数没有自己的this
 箭头函数不会创建自己的this,所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中的this的指向在它在定义时一家确定了,之后不会改变。
 
(3)箭头函数继承来的this指向永远不会改变

 (4) call()、apply()、bind()等方法不能改变箭头函数中的this指向 
 
 (5) 箭头函数不能作为构造函数使用
 
 (6) 箭头函数没有自己的arguments
 
 (7) 箭头函数没有prototype
 
 (8) 箭头函数不能用作Generator函数,不能使用yeild关键字
复制代码

3、New操作符做了什么事情?

1、首先创建了一个新对象
2、设置原型,将对象的原型设置为函数的prototype对象
3、让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
4、判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象

4、vue实现双向数据绑定原理是什么?

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
    <!-- 引入vue文件 -->
    <div id="box">
      <new-input v-bind:name.sync="name"></new-input>
      {{name}}
      <!-- 小胡子语法 -->
      <input type="text" v-model="name" />
    </div>
    <script>
      Vue.component("new-input", {
        props: ["name"],
        data: function () {
          return {
            newName: this.name,
          };
        },
        template: `<label><input type="text" @keyup="changgeName"
        v-model="newName" /> 你的名字:</label>`,
        // 模板字符串
        methods: {
          changgeName: function () {
            this.$emit("update:name", this.newName);
          },
        },
        watch: {
          name: function (v) {
            this.newName = v;
          },
        },
        //    监听
      });

      new Vue({
        el: "#box",
        //挂载实例
        data: {
          name: "nick",
        },
        //赋初始值
      });
    </script>
  </body>
</html>

复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="text" v-mode="msg" />
    <p v-mode="msg"></p>
    <script>
      const data = {
        msg: "你好",
      };
      const input = document.querySelector("input");
      const p = document.querySelector("p");
      input.value = data.msg;
      p.innerHTML = data.msg;
      //视图变数据跟着变
      input.addEventListener("input", function () {
        data.msg = input.value;
      });
      //数据变视图变
      let temp = data.msg;
      Object.defineProperty(data, "msg", {
        get() {
          return temp;
        },
        set(value) {
          temp = value;
          //视图修改
          input.value = temp;
          p.innerHTML = temp;
        },
      });
      data.msg = "小李";
    </script>
  </body>
</html>

5、v-model语法糖是怎么实现的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- v-model 只是语法糖而已 -->
    <!-- v-model 在内部为不同的输入元素使用不同的property并抛出不同的事件 -->
    <!-- text和textarea 元素使用value property 和 input事件 -->
    <!-- checkbox 和radio使用checked  property 和 change事件-->
    <!-- select 字段将value 作为prop 并将change 作为事件 -->
    <!-- 注意:对于需要使用输入法(如中文、日文、韩文等)的语言,你将会发现v-model不会再输入法
    组合文字过程中得到更新 -->
    <!-- 再普通标签上 -->
    <input v-model="sth" />  //这一行等于下一行
    <input v-bind:value="sth" v-on:input="sth = $event.target.value" />
    <!-- 再组件上 -->
    <currency-input v-model="price"></currentcy-input>
        <!--上行代码是下行的语法糖
         <currency-input :value="price" @input="price = arguments[0]"></currency-input>
        --> 
        <!-- 子组件定义 -->
        Vue.component('currency-input', {
         template: `
          <span>
           <input
            ref="input"
            :value="value"
            @input="$emit('input', $event.target.value)"
           >
          </span>
         `,
         props: ['value'],
        })   
</body>
</html>

6、什么是闭包,闭包的作用是什么

当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数。
闭包作用:
局部变量无法共享和长久的保存,而全局变量可能造成变量污染,所以我们希望有一种机制既可以长久的保存变量又不会造成全局污染。
复制代码

7、Promise是什么?

Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态) ;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。

const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";

function MyPromise(fn) {
  // 保存初始化状态
  var self = this;

  // 初始化状态
  this.state = PENDING;

  // 用于保存 resolve 或者 rejected 传入的值
  this.value = null;

  // 用于保存 resolve 的回调函数
  this.resolvedCallbacks = [];

  // 用于保存 reject 的回调函数
  this.rejectedCallbacks = [];

  // 状态转变为 resolved 方法
  function resolve(value) {
    // 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变
    if (value instanceof MyPromise) {
      return value.then(resolve, reject);
    }

    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 只有状态为 pending 时才能转变,
      if (self.state === PENDING) {
        // 修改状态
        self.state = RESOLVED;

        // 设置传入的值
        self.value = value;

        // 执行回调函数
        self.resolvedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
  }

  // 状态转变为 rejected 方法
  function reject(value) {
    // 保证代码的执行顺序为本轮事件循环的末尾
    setTimeout(() => {
      // 只有状态为 pending 时才能转变
      if (self.state === PENDING) {
        // 修改状态
        self.state = REJECTED;

        // 设置传入的值
        self.value = value;

        // 执行回调函数
        self.rejectedCallbacks.forEach(callback => {
          callback(value);
        });
      }
    }, 0);
  }

  // 将两个方法传入函数执行
  try {
    fn(resolve, reject);
  } catch (e) {
    // 遇到错误时,捕获错误,执行 reject 函数
    reject(e);
  }
}

MyPromise.prototype.then = function(onResolved, onRejected) {
  // 首先判断两个参数是否为函数类型,因为这两个参数是可选参数
  onResolved =
    typeof onResolved === "function"
      ? onResolved
      : function(value) {
          return value;
        };

  onRejected =
    typeof onRejected === "function"
      ? onRejected
      : function(error) {
          throw error;
        };

  // 如果是等待状态,则将函数加入对应列表中
  if (this.state === PENDING) {
    this.resolvedCallbacks.push(onResolved);
    this.rejectedCallbacks.push(onRejected);
  }

  // 如果状态已经凝固,则直接执行对应状态的函数

  if (this.state === RESOLVED) {
    onResolved(this.value);
  }

  if (this.state === REJECTED) {
    onRejected(this.value);
  }
};
复制代码

8、Set 和 Map有什么区别?

1、Map是键值对,Set是值得集合,当然键和值可以是任何得值
2、Map可以通过get方法获取值,而set不能因为它只有值
3、都能通过迭代器进行for...of 遍历
4、Set的值是唯一的可以做数组去重,而Map由于没有格式限制,可以做数据存储
复制代码

9、map和foreach有什么区别

foreach()方法会针对每一个元素执行提供得函数,该方法没有返回值,是否会改变原数组取决与数组元素的类型是基本类型还是引用类型
map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值:
复制代码

10、localStorage  sessionStorage  cookies 有什么区别?

localStorage:以键值对的方式存储 储存时间没有限制 永不生效 除非自己删除记录
sessionStorage:当页面关闭后被清理与其他相比不能同源窗口共享 是会话级别的存储方式
cookies 数据不能超过4k 同时因为每次http请求都会携带cookie 所有cookie只适合保存很小的数据 如会话标识
复制代码

11、Vuex有哪些基本属性?为什么 Vuex 的 mutation 中不能做异步操作?

有五种,分别是 State、 Getter、Mutation 、Action、 Module
1、state => 基本数据(数据源存放地)
2、getters => 从基本数据派生出来的数据
3、mutations => 提交更改数据的方法,同步
4、actions => 像一个装饰器,包裹mutations,使之可以异步。
5、modules => 模块化Vuex

1、Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样可以方便地跟踪每一个状态的变化,从而能够实现一些工具帮助更好地了解我们的应用。
2、每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。
复制代码

12、Loader和Plugin 有什么区别

Loader:直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到`loader`。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。 Plugin:直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

其他的下篇更新,收藏网址鸭。

第二篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(二)

第三篇:2022年最新前端面试题,来自这几个月找工作面试和笔试前线,附问题和答案代码,初级前端工程师求职必备(三)

中美程序员对比有什么差别?谁加班多,谁福利好?谁厉害,谁的工资高?

程序开发语言基本都是国外发明的,但是我们在互联网应用上比国外要热闹一点。作为一个新兴的领域,程序员在国内外都是一个很普遍的职业,那我们和国外,尤其是中美程序员对比,有什么区别呢?

下面来自一位横跨太平洋工作的资深程序员的亲身经历分享,作为大家茶余饭后的谈资乐呵乐呵一下。

1.发量和年龄 

我国公司:

  • 我国就很明显了,程序员几乎成为了青春饭。员工平均年龄在30岁以下。35岁焦虑弥漫整个职场,虽然目前收到重视,但情况仍未好转。那么年纪大程序员的都去哪里了呢?有人转岗、有人转行、有人继续在开发岗位,极少数在管理层。希望社会对35的中年人宽容点吧
代表建议放开35岁限制,程序员能摆脱35岁困境吗?

美国公司:

  • 同事里20多到70多岁的都有,众数是三四十的中年人,大部分工作目标都是为了早日退休,攒够钱就随时办退休party。也有些纯粹因为热爱工作、热爱写代码选择不退休的。
  • 我们组的核心成员之一,是位72岁的老头,他每天4点多起床到公司写一会儿代码,等天全亮就戴上头盔去骑山地车锻炼,9点多回公司继续工作。对这老头印象深刻,是因为他逻辑清晰、思路锐利,他是code review小组的成员,经常在邮件里破口大骂其他人写的代码写得有多烂,被投诉,只好在邮件里道歉,过几天继续骂,在我工作的两年里一直循环。
  • 我的另一位资深同事,是位68岁的架构师,热爱工作,每天都乐呵呵的,对我这种新毕业生也很友好,有人问他什么时候退休,他回答说他死的那天。

还有一个被大家津津乐道的话题就是程序员的发量,据说技术行不行,就看头发多还是少?哈哈

程序员工作年龄增加,技术越来越好,发量越来越少
程序员发量逐渐减少

 2. 加班

美国公司:

  • 从没加过班,晚上发版除外(会默认第二天调休)。
  • 经常正开着会,时间到了5点半,产品打断领导说到点了他要回去喂狗(他是一个50岁的不婚族,养了一院子狗),然后就散会下班了。
  • 加班需要申请,有次我申请工作日晚上加班,没批准只好回家了。因为加班费会比较高,需要从项目预算走,领导控制预算不给批。
  • 偶尔周末去办公室取东西,几层停车场只有两三辆车。

我国公司:

  • 996是常事了,据说还是福宝。
  • 印象比较深的是我司之前有个清华本科+美国硕士的小伙子,每天7点半准时下班,结果试用期被辞退了,原因是工作态度不积极,据说后来还和公司打了官司,不知输赢。
加班加到走火入魔

3. 代码质量谁的高 

我国公司:

  • 国内互联网节奏会要快得多,讲究小步快跑,就几天的开发时间,不管三七二十一先上线再说,刚开始我都惊呆了。讲究先有再好,只要能上就先上。

美国公司:

  • 项目在前期花的时间是最多的,比如说需求分析、架构讨论、技术讨论。
  • 写代码会考虑得比较长远,比较有时间去考虑开发原则、维护成本,领导也会乐意去安排版本来解决技术债务。

 4.工作环境和公司文化

美国公司:

  • 老美的公司确实比较尊重员工,在员工关怀上做得比较好。我可以感受到,和领导职位不同,但是我们人格是平等的,彼此尊重。
  • 记得有一次发版前几天,组里程序员说他压力太大,领导给他假期让他放松调整,版本被延迟上线。
  • 美国有family first的文化。有个老印同事,家里老人身体不好,公司同意他回印度工作照顾家人,远程跨国工作。经常有同事因为要看孩子比赛请假。领导自己也会偶尔周五请假,因为要去和女儿一起参加学校的公益活动。
  • 对差异性接受度也比较高。同事有变性人、残疾人,大家相处得都很好。
中美办公环境对比
中美办公环境对比-夸张了

我国公司:

  • 领导高高在上,官威很大。请个假,和求他借钱似的,组长还提醒我让我请假原因不要写“旅游”不然可能会不给批假。
  • 记得有个需求,大家都认为不合理没必要,我去找领导沟通,刚提了一句还没展开,领导直接甩脸色“你是领导还是我是领导”。
  • 有个同事因为耿直,和领导不和,被各种排挤冷暴力,逼他自己辞职拒给赔偿金。
  • 开个线上事故复盘会,做root cause分析,就像要把人钉在耻辱柱一样,我不理解这对解决问题有什么帮助。

其实硬件环境上中美已经差别不大,我们甚至还略胜,但是软件和文化等方面我们还有进步的空间。

如何判断程序员技术水平-看头发多少

 4.工资

美国:

如果汇率不换算的话,国外的软件工程师薪资在10万美元~30万美元不等,与国内的薪资在数字上相差不大(考虑消费水平)。

AI工程师,月薪60k~140k。

软件工程师,月薪69k~183k。

数据科学家,月薪43k~131k。

前端工程师,月薪82k~122k。

我国公司:

国内的薪资水平对应的大公司薪资又是如何的呢?根据拉勾网的岗位薪资数据(截至2020年9月11日),字节、滴滴、大疆以及商汤的薪酬(月薪)大致如下:

字节跳动:

基础架构工程师:30k~60k;

软件工程师(iOS、android):30k~60k;

数据科学家:30k~60k;

前端工程师:15~50k;

滴滴:

AI工程师(自动驾驶):30k~60k,15薪;

软件开发工程师:30k~60k;

数据科学家:20k~100k;

前端工程师:30k~70k;

大疆:

机器学习算法工程师(智能驾驶方向):25k~50k;

前端工程师:12k~40k,部分岗位15薪;

后台开发工程师:15k~25k;

信息安全专家:40k~70k,15薪;

商汤:

前端架构师:35k~60k,15薪;

高级系统开发工程师:30k~70k;

前端开发工程师:15k~35k,15薪;

后端开发工程师:20k~40k,15薪;

事实上,如果汇率不换算的话,国外的软件工程师薪资在10万美元~30万美元不等,与国内的薪资在数字上相差不大(考虑消费水平)

而国外机器学习工程师相关的年薪,则在11万~21万美元之间,数字上甚至会比国内的普遍更低。所以整体上工资体验相差不大,但分具体的工种。

以上的对比,仅仅是一个大牛个人经历的对比,基本上符合大家认知中的国内外区别,但我们也在不断改变,希望短板可以尽快补齐,终有一天我们会和外国程序员面对面坐着喝咖啡或者喝茶。

当前对每个人最重要的是开心工作、保持健康,保住头发、护住绿码。

2022前端趋势展望和2021年前端开发总结

前端开发在过去的一年经历了怎样的发展?2022年前端开发又将出现什么新的技术、应用和趋势?

本文综合各位前端大牛的总结,涵盖:基础框架/工程化、语言、行业发展趋势、底层发展,涉及大前端、微前端、DevOps、5G时代下的前端、浏览器、Vue、React、Web3.0、HTML6.0等前端技术开发热议话题。

1. 基础框架/工程化

随着 jQuery.js 渐渐淡出人们的视野,前端开发框架成为了开发人员必不可少的工具,也成为大家最为关注的东西。

mv* 框架

  • React(Next.js)
  • Vue(nuxt.js)
  • Svelte
  • Angular。

React 即将发布18版本,vue3 成为vue默认版本,Svelte异军突起。

打包工具

  • 传统:Webpack, Rollup, Parcel, Esbuild
  • ESM相关:Snowpack, Vite;ESM的实现:在开发环境编译时,使用 Server 动态编译 + 浏览器的 ESM,基本上实现了“开发环境 0 编译”的功能。而生产环境编译时,则会调用其他编译工具来完成(如 Vite 使用 Rollup)。

语法规范

  • Babel
  • Prettier
  • ESLint

CSS

  • Tailwind CSS(原子类)

web3D

  • Three.js
  • Oasis Engine

跨端

  • React Native
  • Flutter
  • Weex
  • uni-app
  • taro

桌面端

  • Tauri(Webview + Rust/.Net/Go)
  • electron(Chromium + Nodejs)

微前端

  • qiankun
  • single-spa
  • micro-app

E2E 测试

  • cypress(node服务,与程序一起运行)
  • puppeteer(无头浏览器)

shell

  • zx

以下是stateOfJs对2016-2021各个框架的趋势统计:

stateOfJs对2016-2021各个框架的趋势统计

2. 语言

编程语言发展趋势
编程语言排行版
腾讯开发语言排名-
腾讯2020研发大数据报告

_

TIOBE 2022年2月编程语言排行榜

阿特伍德定律:任何可以用 JavaScript 来写的应用,最终都将用 JavaScript 来写。

随着前端应用大型化、复杂化,TypeScript 肯定会越来越普及。未来,TypeScript 是否能得到浏览器和 Node.js 原生支持呢?我们一起期待吧。

前端的同学如果有想学习其他语言的,有如下推荐:

  • Rust 是 JS 基础设施的未来 – Lee Robinson
  • 全栈 —— Go
  • AI —— Python
  • Flutter —— Dart

3. 行业趋势

3.1 前端智能化

  • 低代码(LowCode)其实就是早期的搭建系统、组件平台等(宜搭、微搭),这个概念2014年被著名的研究机构Forrester提出。低代码平台的门槛在逐步降低,从专业的技术人员向业务人员进行转变,中国低代码行业比较分散。
低代码(LowCode)
  • 其中,OutSystems、Mendix、微软Salesforce、ServiceNow 被评为行业领导者。Appian、Oracle 和 Pega 被评为挑战者。Creatio、Kintone、Newgen 和 Quickbase 被评为利基(niche)市场参与者。今年没有厂商被评为远见者。Gartner 预测:“到 2023 年,超过 70% 的企业将采用低代码(LCAP)作为他们发展战略的关键目标之一”。到 2025 年,整体 LCAP(低代码开发平台)市场规模将达到 290 亿美元,年复合增长率超过 20%;其中,LCAP 的细分市场预计将在 2020——2025 年之间,从 44.5 亿美元增长至 143.8 亿美元,复合年增长率为 26.4%。
  • 代码自动生成Sketch2Code,AI 将手绘稿子 转换为 html 代码。imgcook,将Sketch/PSD/图片 转换为 React、Vue、Flutter、小程序等代码。

3.2 大前端(泛前端)

从切图仔、写 HTML 模板的“石器时代”,到前后端分离、大前端的“工业时代”,再到现在跨端技术、低代码的“电气时代”。前端研发的职责一直在改变,同时前端研发需要掌握的技术也在迭代更新。- 字节前端

Serverless

Serverless 是一种基于云计算的简化方式,基本可以理解为 FaaS(函数即服务)+ BaaS(后端即服务),在 BaaS 层进行存储与计算,在 FaaS 层提供云函数。

在 Serverless 的赋能之下,前端工程师能够将页面交互、业务逻辑、数据处理等全部掌控在自己的手中,实现了真正全栈的可能。

全栈

“全栈开发者”是指“同时掌握前端、后端以及其他网站开发相关技能的开发者”。

一个“全栈开发者”可能会使用以下技能点:

前端:JavaScript、H5、CSS3、sass、less、React、Vue、webpack、jest。

后端:Nodejs/Deno、Go、Java、Spring、Gin、Kafka、Hadoop。

数据库:MySQL、mongoDB、redis、clickhouse。

运维:网络协议、CDN、Nginx、ZooKeeper、Docker、Kubernetes。

值得注意的是,一个优秀的工程师并不是以“栈”数取胜,而取决于你解决了什么层次的问题。

DevOps

DevOps(Development 和 Operations 的组合词)是一种重视“软件开发人员(Dev)”和“IT 运维技术人员(OPS)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。在开发、测试、部署、运维等多个领域进行了共建。

与 Kubernetes 相结合:Kubernetes 是一种开源容器编排系统,容器技术的日益普及是 DevOps 出现的因素之一。使用 Kubernetes DevOps,软件开发人员和运维团队可以快速实时地相互交换大量的应用程序,大大提高了生产力。

微前端

微服务架构:微服务架构可以将一个应用分成若干个更小的服务,这让整个开发过程具有很高的敏捷性和可拓展性。

常用的微前端框架包括 qiankun、single-spa、micro-app:

微前端框架排名和发展趋势

微前端我觉得它其实没有太多的趋势。首先微前端就不是一个大家都要用的。微前端沾了微服务的光,但是微服务是所有后端基本上都要往架构上迁, 微前端很明显不是这样的。它更多的是单页应用并有多框架隔离的需求,然后做出微前端这样一个技术方案。我觉得说实话,微前端就不该这么热,包括很多学生都会问我微前端,我反问你有没有看过微前端解决什么样的问题?如果非要往这上边靠的话,就相当于没有困难创造困难也要上,举个例子,公司一共有四五个前端,就非要用微前端架构,四五个人都可以用不同框架,这其实是没必要的。- 程劭非(winter)❞

我比较赞同老师说的,我认为一切技术都为于解决某个问题,关键在于我们有没有找准那个关键的问题,是否在解决这个问题。

小程序

根据winter老师的看法,小程序只是一个前端的技术实现方案,并无大的难点和技术创新,更重要的是看商业模式上的考量。

阿拉丁《2021 年度小程序互联网发展白皮书》

上图截选自:阿拉丁《2021 年度小程序互联网发展白皮书》

解决小程序的跨平台开发问题可以采用框架转换:uni-app(Vue)、taro(React)。

5G时代

5G 时代到来,5G将与超高清视频、VR、AR、消费级云计算、智能家居、智慧城市、车联网、物联网、智能制造等产生深度融合,这些都将为前端技术的发展带来新的增长和机遇。WebGL、WebGPU等技术也将迎来一波发展的机会。

  • Web 3D3D 类的 H5 小游戏、在线看房、电子商务、在线教育等,对于技术而言这无疑是一片沃土。随着 5G 技术发展,视频加载速度会非常快,简单的实时渲染会被视频直接替代。复杂的可以通过服务器渲染,将画面传回网页中,只要传输够快,手机的性能就不再是问题。相关的一些库:Three.jsOasis EngineBabylon.jsPlayCanvas.js
  • WebRTC (Web Real-Time Communications)传统的技术包括:XMLHttpRequest,WebSocket,未来:WebRTC 会在点对点私密传输、娱乐领域,元宇宙领域,低延迟领域大放异彩。

4. 底层演进

前端历年大事件

2021 JavaScript大事件 ↓

「JavaScript」

8.24:TypeScript 新官网上线

12.4:JavaScript 26 岁了

「Node.js」

2.2:npm 7.0 正式可用

3.29:Deno 公司成立

4.21:Node.js 16 发布

7.20:Node-RED 2.0 发布,低代码编程工具

9.20:Node.js 发布 Corepack,用于管理npm、yarn、pnpm、cnpm

10.19:Node.js 17 发布

「Vue」

8.3:Vue.js 被选作维基百科的前端框架

8.5:Vue 3.2 发布

11.24:Pinia 正式成为 vuejs 的一员

「React」

5.28:React 18 alpha 发布

10.5:React 全新文档发布

11.27:Next.js 12 发布

12.14:Create React App 5.0 发布

「打包工具」

2021.1.6 Snowpack 3.0 发布

2021.2.17 Vite 2.0 发布

2021.10.13 Parcel v2 发布

「其他」

2021.3.6 jQuery 3.6.0 发布

2021.3.17 Chrome V8 9.0 发布

2021.10.7 jQuery Mobile 弃用

2021.11.4 Angular v13 发布

浏览器

Chrome 一家独大,IE 浏览器将于 2022 年 6 月 15 日正式停用。

谷歌浏览器几乎独霸移动浏览器市场

HTML6.0

支持原生模式、没有 JavaScript 的单页应用程序、自由调整图像大小、专用库、微格式、自定义菜单、增强身份验证、集成摄像头。

WebAssembly

WebAssembly 简称 Wasm,是一种可在 Web 中运行的全新语言格式,同时兼具体积小、性能高、可移植性强等特点,在底层上类似 Web 中的 JavaScript,同时也是 W3C 承认的 Web 中的第 4 门语言。

在前端的游戏、音乐、视频等领域大放异彩,目前很多桌面软件也纷纷通过编译成 Wasm 的形式搬进了浏览器中。

2022 年 Wasm 功能将会不断完善,同时也会有越来越多的传统 PC 软件推出 Web 版本。

2022 Wasm

开源

首次被列入十四五规划,2021年,中国企业积极构建开源平台。根据GitHub统计,中国开发者已成为全球最大规模的开发者群体。

元宇宙

游戏、VR/AR、区块链数字资产等等概念的整合。

web 3.0

web1.0: 单向信息,只读;web 2.0的标志:User Generated Content(用户生成内容,例如微博、Facebook);web3.0: 人和网络以及网络与人的沟通。

5. 总结

在工业4.0的大背景下,随着人工智能、云计算、大数据、物联网、区块链等互联网潮流技术的不断推进,互联网行业走向工业化和智能化。全球疫情的常态化,越来越多的公司选择或者不得不居家办公(WFH),必然给前端行业带来更多的机会。

2023 年底全球软件开发人员达到 2770万,中国将占6%至8%,前端预计30万左右,而JavaScript 在全球目前约有 1400 万开发者。

2005左右才出现前端的岗位,变化非常快,目前还是处在发展期(好事儿),只有把握底层变化,不断思辨和学习,才能把焦虑控制在一定范围内。

另外说到“卷”,还是上进心导致的,对吧?真想躺的话,能躺的办法还是挺多的。如果想要进前端的领域,从学习的角度来讲,我推荐 hard way。也就是说,我们看起来最难的那条路反而是最简单的,那些看起来简单的路,它有可能反而是更绕。你想往山顶上走,肯定选择最陡峭的,你想走下坡路,肯定选择最远的那条路。这个道理是是我想今天传达给大家的,原因还是在于看到太多的同学们想走捷径,或者说想走简单的路,结果反而越走越远,最后绕回来的话反而消耗更大。- 程劭非(winter)❞

最后,小厂前端团队押宝什么?

押技术落地,押Vue3.0、TS、Three.js,押年轻人!

希望此文有助于大家的学习和提升,以更强的自己面对技术的迭代和外部不断增加的不确定性。

共勉!

来自:作者:大清,掘金社区

《浏览器基本原理与实践》36点总结,让我重新认识浏览器

前言

浏览器是每一名前端开发日常工作打交道最多(之一)的,或者说前端工作的内容大部分都是基于浏览器环境来的,因为最终成果需要在浏览器运行和验证。

浏览器工作原理

但对大部分前端开发来说,浏览器就是一个最熟悉的陌生人,经常用,却没几个人说得清其运行原理。不过浏览器确实也很复杂,想想到现在我们“国产替代”都失败了。比如几个简单的问题:

比如js是怎样运行的呢?

精美样式页面是怎样渲染到电脑屏幕的呢?

在开放的互联网它又是怎样保证我们个人信息安全的呢?

带着打破砂锅问到底的态度,开始肝李兵老师的《浏览器基本原理与实践》,下面是研读本书后的36点总结,希望有益于大家。

1. Chrome 架构:仅仅打开了 1 个页面,为什么有 4 个进程

线程和进程区别
多线程可以并行处理任务,线程不能单独存在,它是由进程来启动和管理的。一个进程是一个程序的运行实例。

线程和进程的关系
1、进程中任意一线程执行出错,都会导致整个进程的崩溃。
2、线程之间共享进程中的数据。
3、当一个进程关闭后,操作系统会回收进程所占用的内存。
4、进程之间的内容相互隔离。

单进程浏览器
1、不稳定。单进程中的插件、渲染线程崩溃导致整个浏览器崩溃。
2、不流畅。脚本(死循环)或插件会使浏览器卡顿。
3、不安全。插件和脚本可以获取到操作系统任意资源。

多进程浏览器
1、解决不稳定。进程相互隔离,一个页面或者插件崩溃时,影响仅仅时当前插件或者页面,不会影响到其他页面。
2、解决不流畅。脚本阻塞当前页面渲染进程,不会影响到其他页面。
3、解决不安全。采用多进程架构使用沙箱。沙箱看成时操作系统给进程上来一把锁,沙箱的程序可以运行,但是不能在硬盘上写入任何数据,也不能在敏感位置读取任何数据。

多进程架构
分为 浏览器进程、渲染进程、GPU 进程、网络进程、插件进程。

缺点
1、资源占用高。
2、体系架构复杂。

面向服务架构
把原来的各种模块重构成独立的服务,每个服务都可以在独立的进程中运行,访问服务必须使用定义好的接口,通过 IPC 通讯,使得系统更内聚、松耦合、易维护和拓展。

2. TCP 协议:如何保证页面文件能被完整送达浏览器

  • IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息;
  • UDP 头中除了目的端口,还有源端口号等信息;
  • IP 负责把数据包送达目的主机;
  • UDP 负责把数据包送达具体应用;
  • 对于错误的数据包,UDP 不提供重发机制,只是丢弃当前的包,不能保证数据的可靠性,但是传输速度非常块;
  • TCP 头除了包含了目标端口和本机端口号外,还提供了用于排序的序列号,保证了数据完整地传输,它的连接可分为三个阶段:建立连接、传输数据和断开连接;

3. HTTP 请求流程:为什么很多站点第二次打开速度会很快

  • 浏览器中的 HTTP 请求从发起到结束一共经历如下八个阶段:构建请求、查找缓存、准备 IP 和端口、等待 TCP 队列、建立 TCP 连接、发起 HTTP 请求、服务器处理请求、服务器返回请求和断开连接;
  • 构建请求。浏览器构建请求行,构建好后,准备发起网络请求;
  • 查找缓存。在真正发起请求前浏览器会查询缓存中是否有请求资源副本,有则拦截请求,返回资源副本,否则进入网络请求;
  • 准备 IP 地址和端口。HTTP 网络请求需要和服务器建立 TCP 连接,而建立 TCP 连接需要准备 IP 地址和端口号,浏览器需要请求 DNS 返回域名对应的 IP,同时会缓存域名解析结果,供下次查询使用;
  • 等待 TCP 队列。Chrome 机制,同一个域名同时最多只能建立 6 个 TCP 连接;
  • 建立 TCP 连接。TCP 通过“三次握手”建立连接,传输数据,“四次挥手”断开连接;
  • 发送 HTTP 请求。建立 TCP 连接后,浏览器就可以和服务器进行 HTTP 数据传输了,首先会向服务器发送请求行,然后以请求头形式发送一些其他信息,如果是 POST 请求还会发送请求体;
  • 服务器处理请求。首先服务器会返回响应行,随后,服务器向浏览器发送响应头和响应体。通常服务器返回数据,就要关闭 TCP 连接,如果请求头或者响应头有 Connection:keep-alive TCP 保持打开状态;

4. 导航流程:从输入 URL 到页面展示这中间发生了什么

  • 用户输入 URL 并回车
  • 浏览器进程检查 URL,组装协议,构成完整 URL
  • 浏览器进程通过进程通信(IPC)把 URL 请求发送给网络进程
  • 网络进程接收到 URL 请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程
  • 如果没有,网络进程向 web 服务器发起 http 请求(网络请求),请求流程如下:
    • 进行 DNS 解析,获取服务器 IP 地址,端口
    • 利用 IP 地址和服务器建立 tcp 连接
    • 构建请求头信息
    • 发送请求头信息
    • 服务器响应后,网络进程接收响应头和响应信息,并解析响应内容
  • 网络进程解析响应流程:
    • 检查状态码,如果是 301/302,则需要重定向,从 Location 自动读取地址,重新进行第 4 步,如果是 200,则继续处理请求
    • 200 响应处理:检查响应类型 Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行后续渲染。如果是 html 则通知浏览器进程准备渲染进程进行渲染
  • 准备渲染进程
    • 浏览器进程检查当前 URL 是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程
  • 传输数据、更新状态
    • 渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”
    • 渲染进程接收完数据后,向浏览器发送“确认提交”
    • 浏览器进程接收到确认消息后 engine 浏览器界面状态:安全、地址 URL、前进后退的历史状态、更新 web 页面

5. 渲染流程(上):HTML、CSS 和 JavaScript 是如何变成页面的

  • 浏览器不能直接理解 HTML 数据,需要将其转化为 DOM 树结构;
  • 生成 DOM 树后,根据 CSS 样式表,计算出 DOM 树所有节点样式;
  • 创建布局树:遍历 DOM 树所有可见节点,把这些节点加到布局中,不可见节点忽略,如 head 标签下所有内容,display: none 元素;

6. 渲染流程(下):HTML、CSS 和 JavaScript 是如何变成页面的

  • 分层:层叠上下文属性的元素(比如定位属性元素、透明属性元素、CSS 滤镜属性元素)提升为单独的一层,需要裁剪的地方(比如出现滚动条)也会被创建为图层;
  • 图层绘制:完成图层树构建后,渲染引擎会对图层树每一层进行绘制,把一个图层拆分成小的绘制指令,再把指令按照顺序组成一个带绘制列表;
  • 有些情况图层很大,一次绘制所有图层内容,开销太大,合成线程会将图层划分为图块(256×256 或者 512×512);
  • 合成线程将图块提交给栅格线程进行栅格化,将图块转换为位图。栅格化过程都会使用 GPU 加速,生成的位图保存周期 GPU 内存中;
  • 一旦所有图块都被栅格化,合成线程会生成一个绘制图块命令(DrawQuad),然会将命令提交给浏览器进程,viz 组件接收到该指令,将页面内容绘制到内存中,显示在屏幕上;
  • 重排:通过 JavaScript 或者 CSS 修改元素几何位置属性,会触发重新布局,解析后面一系列子阶段;重绘:不引起布局变换,直接进入绘制及其以后子阶段;合成:跳过布局和绘制阶段,执行的后续操作,发生在合成线程,非主线程;

7. 变量提升:javascript 代码是按顺序执行的吗

  • JavaScript 代码在执行之前需要先编译,在编译阶段,变量和函数会被存放到变量环境中,变量默认值会被设置为 undefined;
  • 在代码执行阶段,JavaScript 引擎会从变量环境中查找自定义的变量和函数;
  • 如果在编译阶段,窜爱两个相同的函数,那么最终放在变量环境中的是最后定义的那个,后定义的覆盖先定义的;

8. 调用栈:为什么 JavaScript 代码会出现栈溢出

  • 每调用一个函数,JavaScript 引擎会为其创建执行上下文压入调用栈,然后,JavaScript 引擎开始执行函数代码。
  • 如果一个函数 A 调用另外一个函数 B,那么 JavaScript 引擎会为 B 函数创建执行上下文,并将 B 函数的执行上下文压入栈顶。
  • 当前函数执行完毕后,JavaScript 引擎会将该函数的执行上下文弹出栈。
  • 当分配的调用栈空间被占满时,会引发“堆栈溢出”问题。

9. 块级作用域:var 缺陷以及为什么要引入 let 和 const

  • let、const 申明的变量不会被提升。在 javascript 引擎编译后,会保存在词法环境中。
  • 块级作用域在代码执行时,将 let、const 变量存放在词法环境的一个单独的区域。词法环境内部维护一个小型的栈结构,作用域内部变量压入栈顶。作用域执行完,从栈顶弹出。

10. 作用域链和闭包:代码中出现相同的变量,JavaScript 引擎如何选择

  • 使用一个变量,JavaScript 引擎会在当前的执行上下文中查找变量,如果没有找到,会继续在 outer(执行环境指向外部执行上下文的引用)所指向的执行上下文中查找;
  • JavaScript 执行过程,作用域链是由词法作用域决定,而词法作用域是由代码中函数声明的位置决定;
  • 根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使外部函数已经执行结束了,但是内部函数引用外部函数的变量依旧保存在内存中,把这些变量的集合称为闭包;

11. this:从 JavaScript 执行上下文视角讲 this

当执行 new CreateObj 的时候,JavaScript 引擎做了四件事:

  • 首先创建一个控对象 tempObj;
  • 接着调用 CreateObj.call 方法,并将 tempObj 作为 call 方法的参数,这样当 createObj 的执行上下文创建时,它的 this 就指向 tempObj 对象;
  • 然后执行 CreateObj 函数,此时的 CreateObj 函数执行上下文中的 this 指向 tempObj 对象;
  • 最后返回 tempObj 对象。

this 的使用分为:

  • 当函数最为对象的方法调用时,函数中的 this 就是该对象;
  • 当函数被正常调用时,在严格模式下,this 值是 undefined,非严格模式下 this 指向的是全局对象 window;
  • 嵌套函数中的 this 不会继承外层函数的 this 值;
  • 箭头函数没有自己的执行上下文,this 是外层函数的 this。

12. 栈空间和堆空间:数据是如何存储的

动态语言:在使用时需要检查数据类型的语言。
弱类型语言:支持隐式转换的语言。

JavaScript 中的 8 种数据类型,它们可以分为两大类——原始类型和引用类型。
原始类型数据存放在栈中,引用类型数据存放在堆中。堆中的数据是通过引用与变量关系联系起来的。

从内存视角了解闭包:词法扫描内部函数,引用了外部函数变量,堆空间创建一个“closure”对象,保存变量。

13. 垃圾回收:垃圾数据如何自动回收

  • 栈中数据回收:执行状态指针 ESP 在执行栈中移动,移过某执行上下文,就会被销毁;
  • 堆中数据回收:V8 引擎采用标记-清除算法;
  • V8 把堆分为两个区域——新生代和老生代,分别使用副、主垃圾回收器;
  • 副垃圾回收器负责新生代垃圾回收,小对象(1 ~ 8M)会被分配到该区域处理;
  • 新生代采用 scavenge 算法处理:将新生代空间分为两半,一半空闲,一半存对象,对对象区域做标记,存活对象复制排列到空闲区域,没有内存碎片,完成后,清理对象区域,角色反转;
  • 新生代区域两次垃圾回收还存活的对象晋升至老生代区域;
  • 主垃圾回收器负责老生区垃圾回收,大对象,存活时间长;
  • 新生代区域采用标记-清除算法回收垃圾:从根元素开始,递归,可到达的元素活动元素,否则是垃圾数据;
  • 为了不造成卡顿,标记过程被切分为一个个子标记,交替进行。

14. 编译器和解析器:V8 如何执行一段 JavaScript 代码的

  • 计算机语言可以分为两种:编译型和解释型语言。编译型语言经过编译器编译后保留机器能读懂的二进制文件,比如 C/C++,go 语言。解释型语言是在程序运行时通过解释器对程序进行动态解释和执行,比如 Python,JavaScript 语言。
  • 编译型语言的编译过程:编译器首先将代码进行词法分析、语法分析,生成抽象语法树(AST),然后优化代码,最后生成处理器能够理解的机器码;
  • 解释型语言解释过程:解释器会对代码进行词法分析、语法分析,并生产抽象语法树(AST),不过它会再基于抽象语法树生成字节码,最后根据字节码执行程序;
  • AST 的生成:第一阶段是分词(词法分析),将一行行源码拆解成一个个 token(语法上不可再分、最小单个字符)。第二阶段是解析(语法分析),将上一步生成的 token 数据,根据语法规则转为 AST,这一阶段会检查语法错误;
  • 字节码存在的意义:直接将 AST 转化为机器码,执行效率是非常高,但是消耗大量内存,从而先转化为字节码解决内存问题;
  • 解释器 ignition 在解释执行字节码,同时会手机代码信息,发现某一部分代码是热点代码(HotSpot),编译器把热点的字节码转化为机器码,并保存起来,下次使用;
  • 字节码配合解释器和编译器的计数实现称为即时编译(JIT)。

15. 消息队列和事件循环:页面是怎么活起来的

  • 每个渲染进程都有一个主线程,主线程会处理 DOM,计算样式,处理布局,JavaScript 任务以及各种输入事件;
  • 维护一个消息队列,新任务(比如 IO 线程)添加到消息队列尾部,主线程循环地从消息队列头部读取任务,执行任务;
  • 解决处理优先级高的任务:消息队列的中的任务称为宏任务,每个宏任务中都会包含一个微任务队列,在执行宏任务的过程中,如果 DOM 有变化,将该变化添加到微任务队列中;
  • 解决单个任务执行时长过久:JavaScript 通过回调功能来规避。

16. webapi:setTimeout 是怎么实现的

  • JavaScript 调用 setTimeout 设置回调函数的时候,渲染进程会创建一个回调任务,延时执行队列存放定时器任务;
  • 当定时器任务到期,就会从延时队列中取出并执行;
  • 如果当前任务执行时间过久,会影响延时到期定时器任务的执行;
  • 如果 setTimeout 存在嵌套调用(5 次以上),判断该函数方法被阻塞,那么系统会设置最短时间间隔为 4 秒;
  • 未激活的页面,setTimeout 执行最小间隔是 1000 毫秒,目的是为了降低加载损耗;
  • 延时执行时间最大值是 24.8 天,因为延时值是以 32 个 bit 存储的;
  • setTimeout 设置的回调函数中的 this 指向全局 window。

17. webpai:XMLHttpRequest 是怎么实现的

  • XMLHttpRequest onreadystatechange 处理流程:未初始化 -> OPENED -> HEADERS_RECEIVED -> LOADING -> DONE;
  • 渲染进程会将请求发送给网络进程,然后网络进程负责资源下载,等网络进程接收到数据后,利用 IPC 通知渲染进程;
  • 渲染进程接收到消息之后,会将 xhr 回调函数封装成任务并添加到消息队列中,等主线程循环系统执行到该任务的时候,会根据相关状态来调用回调函数。

18. 宏任务和微任务:不是所有的任务都是一个待遇

  • 消息队列中的任务为宏任务。渲染进程内部会维护多个消息队列,比如延时执行队列和普通消息队列,主线程采用 for 循环,不断地从这些任务队列中取出任务并执行;
  • 微任务是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前;
  • V8 在执行 javascript 脚本时,会为其创建一个全局执行上下文,同时会创建一个微任务队列;
  • 执行微任务过程中产生的微任务不会推迟到下个宏任务中执行,而是在当前宏任务中继续执行;

19. 使用 Promise 告别回调函数

  • 使用 Promise 解决了回调地狱问题,消灭嵌套和多次处理;
  • 模拟实现 Promise
function Bromise(executor) {  var _onResolve = null  this.then = function (onResolve) {    _onResolve = onResolve  }  function resolve(value) {    setTimeout(() => {      _onResolve(value)    }, 0)  }  executor(resolve, null)}

20. async await 使用同步方式写异步代码

  • 生成器函数是一个带星号函数,而且是可以暂停执行和回复执行的;
  • 生成器函数内部执行一段代码,遇到 yield 关键字,javascript 引擎返回关键字后面的内容给外部,并且暂停该函数的执行;
  • 外部函数可以同步 next 方法恢复函数的执行;
  • 协程是一种比线程更加轻量级的存在,协程可以看成是跑在线程上的任务,一个线程可以存在多个协程,但是同时只能执行一个协程,如果 A 协程启动 B 协程,A 为 B 的父协程;
  • 协程不被操作协同内核所管理,而完全由程序所控制,这样性能提升;
  • await xxx 会创建一个 Promise 对象,将 xxx 任务提交给微任务队列;
  • 暂停当前协程的执行,将主线程的控制权力转交给父协程执行,同时将 Promise 对象返回给父协程,继续执行父协程;
  • 父协程执行结束之前会检查微任务队列,微任务队列中有 resolve(xxx) 等待执行,触发 then 的回调函数;
  • 回调函数被激活后,会将主线程的控制权交给协程,继续执行后续语句,完成后将控制权还给父协程。

21. 页面性能分析:利用 chrome 做 web 性能分析

  • Chrome 开发者工具(简称 DevTools)是一组网页制作和调试的工具,内嵌于 Google Chrome 浏览器中。它一共包含了 10 个功能面板,包括了 Elements、Console、Sources、NetWork、Performance、Memory、Application、Security、Audits 和 Layers。

22. DOM 树:JavaScript 是如何影响 DOM 树构建的

  • HTML 解析器(HTMLParse)负责将 HTML 字节流转换为 DOM 结构;
  • HTML 解析器并不是等整个文档加载完成之后再解析,而是网络进程加载流多少数据,便解析多少数据;
  • 字节流转换成 DOM 三个阶段:1、字节流转换为 Token;2、维护一个 Token 栈,遇到 StartTag Token 入栈,遇到 EndTag Token 出栈;3、为每个 Token 创建一个 DOM 节点;
  • JavaScript 文件和 CSS 样式表文件都会阻塞 DOM 解析;

23. 渲染流水线:CSS 如何影响首次加载时的白屏时间?

  • DOM 构建结束之后,css 文件还未下载完成,渲染流水线空闲,因为下一步是合成布局树,合成布局树需要 CSSOM 和 DOM,这里需要等待 CSS 加载结束并解析成 CSSOM;
  • CSSOM 两个作用:提供给 JavaScript 操作样式表能力,为布局树的合成提供基础样式信息;
  • 在执行 JavaScript 脚本之前,如果页面中包含了外部 CSS 文件的引用,或者通过 style 标签内置了 CSS 内容,那么渲染引擎还需要将这些内容转化为 CSSOM,因为 JavaScript 有修改 CSSOM 的能力,所以在执行 JavaScript 之前,还需要依赖 CSSOM。也就是说 CSS 在部分情况下也会阻塞 DOM 的生成。

24. 分层和合成机制:为什么 CSS 动画比 JavaScript 高效

  • 显示器固定刷新频率是 60HZ,即每秒更新 60 张图片,图片来自显卡的前缓冲区;
  • 显卡的职责是合成新的图像,保存在后缓冲区,然后后缓冲区和前缓冲区互换,显卡更新频率和显示前刷新频率不一致,就会造成视觉上的卡顿;
  • 渲染流水线生成的每一副图片称为一帧,生成一帧的方式有重排、重绘和合成三种;
  • 重排会根据 CSSOM 和 DOM 计算布局树,重绘没有重新布局阶段;
  • 生成布局树之后,渲染引擎根据布局树特点转化为层树,每一层解析出绘制列表;
  • 栅格线程根据绘制列表中的指令生成图片,每一层对应一张图片,合成线程将这些图片合成一张图片,发送到后缓存区;
  • 合成线程会将每个图层分割成大小固定的图块,优先绘制靠近视口的图块;

25. 页面性能:如何系统优化页面

  • 加载阶段:减少关键资源个数,降低关键资源大小,降低关键资源的 RTT 次数;
  • 交互阶段:减少 JavaScript 脚本执行时间,避免强制同步布局:操作 DOM 的同时获取布局样式会引发,避免布局抖动:多次执行强制布局和抖动,合理利用 CSS 合成动画:标记 will-change,避免频繁的垃圾回收;
  • CSS 实现一些变形、渐变、动画等特效,这是由 CSS 触发的,并且是在合成线程中执行,这个过程称为合成,它不会触发重排或者重绘;

26. 虚拟 DOM:虚拟 DOM 和真实 DOM 有何不同

  • 当有数据更新时, React 会生产一个新的虚拟 DOM,然会拿新的虚拟 DOM 和之前的虚拟 DOM 进行比较,这个过程找出变化的节点,然后将变化的节点应用到 DOM 上;
  • 最开始的时候,比较两个 DOM 的过程是在一个递归函数里执行的,其核心算法是 reconciliation。通常情况,这个比较过程执行很快,不过虚拟 DOM 比较复杂时,执行比较函数可能占据主线程比较久的时间,这样会导致其他任务的等待,造成页面卡顿。React 团队重写了 reconciliation 算法,称为 Fiber reconciler,之前老的算法称为 Stack reconciler;

27. PWA:解决 web 应用哪些问题

  • PWA(Progressive Web App),渐进式 Web 应用。一个渐进式过渡方案,让普通站点过渡到 Web 应用,降低站点改造代价,逐渐支持新技术,而不是一步到位;
  • PWA 引入 ServiceWorker 来试着解决离线存储和消息推送问题,引入 mainfest.json 来解决一级入口问题;
  • 暗转了 ServiceWorker 模块之后,WebApp 请求资源时,会先通过 ServiceWorker,让它判断是返回 Serviceworker 缓存的资源还是重新去网络请求资源,一切的控制权交给 ServiceWorker 来处理;
  • 在目前的 Chrome 架构中,Service Worker 是运行在浏览器进程中的,因为浏览器进程生命周期是最长的,所以在浏览器的生命周期内,能够为所有的页面提供服务;

28. WebComponent:像搭积木一样构建 web 应用

  • CSS 的全局属性会阻碍组件化,DOM 也是阻碍组件化的一个因素,因为页面中只有一个 DOM,任何地方都可以直接读取和修改 DOM;
  • WebComponent 提供了对局部试图封装能力,可以让 DOM、CSSOM 和 JavaScript 运行在局部环境中;
  • template 创建模版,查找模版内容,创建影子 DOM,模版添加到影子 DOM 上;
  • 影子 DOM 可以隔离全局 CSS 和 DOM,但是 JavaScript 是不会被隔离的;

29. HTTP1:HTTP1 性能优化

  • HTTP/0.9 基于 TCP 协议,三次握手建立连接,发送一个 GET 请求行(没有请求头和请求体),服务器接收请求之后,读取对应 HTML 文件,数据以 ASCII 字符流返回,传输完成断开连接;
  • HTTP/1.0 增加请求头和响应头来进行协商,在发起请求时通过请求头告诉服务器它期待返回什么类型问题、什么形式压缩、什么语言以及文件编码。引入来状态吗,Cache 机制等;
  • HTTP/1.1 改进持久化连接,解决建立 TCP 连接、传输数据和断开连接带来的大量开销,支持在一个 TCP 连接上可以传输多个 HTTP 请求,目前浏览器对于一个域名同时允许建立 6 个 TCP 持久连接;
  • HTTP/1.1 引入 Chunk transfer 支持动态生成内容:服务器将数据分割成若干任意大小的数据块,每个数据块发送时附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。在 HTTP/1.1 需要在响应头中设置完整的数据大小,如 Content-Length。

30. HTTP2:如何提升网络速度

  • HTTP/1.1 主要问题:TCP 慢启动;同时开启多条 TCP 连接,会竞争固定宽带;对头阻塞问题;
  • HTTP/2 在一个域名下只使用一个 TCP 长连接和消除对头阻塞问题;
  • 多路复用的实现:HTTP/2 添加了二进制分帧层,将发送或响应数据经过二进制分帧处理,转化为一个个带有请求 ID 编号的帧,服务器或者浏览器接收到响应帧后,根据相同 ID 帧合并为一条完整信息;
  • 设置请求优先级:发送请求可以设置请求优先级,服务器可以优先处理;
  • 服务器推送:请求一个 HTML 页面,服务器可以知道引用了哪些 JavaScript 和 CSS 文件,附带一起发送给浏览器;
  • 头部压缩:对请求头和响应头进行压缩;

31. HTTP3:甩掉 TCP、TCL 包袱,构建高效网络

  • 虽然 HTTP/2 解决了应用层面的对头阻塞问题,不过和 HTTP/1.1 一样,HTTP/2 依然是基于 TCP 协议,而 TCP 最初是为了单连接而设计;
  • TCP 可以看成是计算机之间的一个虚拟管道,数据从一端发送到另一端会被拆分为一个个按照顺序排列的数据包,如果在传输过程中,有一个数据因为网络故障或者其他原因丢失,那么整个连接会处于暂停状态,只有等到该数据重新传输;
  • 由于 TCP 协议僵化,也不可能使用新的协议,HTTP/3 选择了一个折衷的方法,基于现有的 UDP 协议,实现类似 TC 片多路复用,传输可靠等功能,称为 QULC 协议;
  • QULC 实现类似 TCP 流量控制,传输可靠功能;集成 TLS 加密功能;实现多路复用功能;

32. 同源策略:为什么 XMLHttpRequst 不能跨域请求

  • 协议、域名和端口号相同的 URL 是同源的;
  • 同源策略会隔离不同源的 DOM、页面数据和网络通信;
  • 页面可以引用第三方资源,不过暴露出诸如 XSS 问题,引入内容安全策略 CSP 限制;
  • 默认 XMLHttpRequest 和 Fetch 不能跨站请求资源,引入跨域资源共享(CORS)进行跨域访问控制;

33. 跨站脚本攻击 XSS:为什么 cookie 中有 httpOnly 属性

  • XSS 跨站脚本,往 HTML 文件中注入恶意代码,对用户实施攻击;
  • XSS 攻击主要有存储型 XSS 攻击、反射型 XSS 攻击和 DOM 的 XSS 攻击;
  • 阻止 XSS 攻击:服务器对脚本进行过滤或转码,利用 CSP 策略,使用 HttpOnly;

34. CSRF 攻击:陌生连接不要随便点

  • CSRF 跨站请求伪造,利用用户的登录状态,通过第三方站点攻击;
  • 避免 CSRF 攻击:利用 SameSite(三种模式:Strict、Lax、None) 让浏览器禁止第三方站点发起请求携带关键 Cookie;验证请求的来源站点,请求头中的 Referer 和 Origin 属性;利用 CSRF Token;

35. 沙盒:页面和系统之间的隔离墙

  • 浏览器被划分为浏览器内核和渲染内核两个核心模块,其中浏览器内核石油网络进程、浏览器主进程和 GPU 进程组成的,渲染内核就是渲染进程;
  • 浏览器中的安全沙箱是利用操作系统提供的安全技术,让渲染进程在执行过程中无法访问或者修改操作系统中的数据,在渲染进程需要访问系统资源的时候,需要通过浏览器内核来实现,然后将访问的结果通过 IPC 转发给渲染进程;
  • 站点隔离(Site Isolation)将同一站点(包含相同根域名和相同协议的地址)中相互关联的页面放到同一个渲染进程中执行;
  • 实现站点隔离,就可以将恶意的 iframe 隔离在恶意进程内部,使得它无法继续访问其他 iframe 进程的内容,因此无法攻击其他站点;

36. HTTPS:让数据传输更安全

  • 在 TCP 和 HTTP 之间插入一个安全层,所有经过安全层的数据都会被加密或者解密;
  • 对称加密:浏览器发送加密套件列表和一个随机数 client-random,服务器会从加密套件中选取一个加密套件,然后生成一个随机数 service-random,返回给浏览器。这样浏览器和服务器都有相同 client-random 和 service-random,再用相同的方法将两者混合生成一个密钥 master secret,双方就可以进行数据加密传输了;
  • 对称加密缺点:client-random 和 service-random 的过程都是明文,黑客可以拿到协商的加密套件和双方随机数,生成密钥,数据可以被破解;
  • 非对称加密:浏览器发送加密套件列表给服务器,服务器选择一个加密套件,返回加密套件和公钥,浏览器用公钥加密数据,服务器用私钥解密;
  • 非对称加密缺点:加密效率太低,不能保证服务器发送给浏览器的数据安全,黑客可以获取公钥;
  • 对称加密结合非对称加密:浏览器发送对称加密套件列表、非对称加密列表和随机数 client-random 给服务器,服务器生成随机数 service-random,选择加密套件和公钥返回给浏览器,浏览器利用 client-random 和 service-random 计算出 pre-master,然后利用公钥给 pre-master 加密,向服务器发送加密后的数据,服务器用私钥解密出 pre-master 数据,结合 client-random 和 service-random 生成对称密钥,使用对称密钥传输加密数据;
  • 引入数字证书是为了证明“我就是我”,防止 DNS 被劫持,伪造服务器;
  • 证书的作用:一个是向浏览器证明服务器的身份,另一个是包含服务器公钥;
  • 数字签名过程:CA 使用 Hash 函数技术明文信息,得出信息摘要,然后 CA 使用私钥对信息摘要进行加密,加密后的秘文就是数字签名;
  • 验证数字签名:读取证书明文信息,使用相同 Hash 函数计算得到信息摘要 A,再利用 CA 的公钥解密得到 B,对比 A 和 B,如果一致,则确认证书合法;

web前端号整理,来源:wuwhs[segmentfault]

2022年这几款VSCode前端插件让你效率高到飞起,开发如虎添翼,面试必备

前言

正所谓工欲善其事,必先利其器,学会利用好前端开发插件,简直就是如虎添翼,绝对让你的工作倍儿爽,效率高到飞起,面试绝对能装到。

话不多说,上干货

开发综合推荐

别名路径跳转

插件名:别名路径跳转

使用说明: 别名路径跳转插件,支持任何项目,

使用场景: 当你在开发页面时, 想点击别名路径导入的组件时(演示如下)

配置说明

  • 下载后只需自定义配置一些自己常用的别名路径即可// 文件名别名跳转
      "alias-skip.mappings": {
        "~@/": "/src",
        "views": "/src/views",
        "assets": "/src/assets",
        "network": "/src/network",
        "common": "/src/common"
      },
    • 右击插件–》扩展设置–》路径映射在settinas.json中编辑

路径别名智能提示

  • 插件名:path-alias
  • 场景: 在导入组件的时候,使用别名路径没用提示时👇 (可和别名路径跳转同时使用, 无冲突)
  • 详细使用教程(贼简单)

安装效果和功能

indent-rainbow

  • 插件名: indent-rainbow
  • 功能:彩虹缩进

Bracket Pair Colorizer 2

  • 插件名: Bracket Pair Colorizer 2
  • 功能:给匹配的括号() 或者 对象{}.. 添加对应的颜色用于区分

Auto Rename Tag

  • 插件名: Auto Rename Tag
  • 功能:自动重命名标签

Code Spell Checker

  • 插件名:Code Spell Checker
  • 功能:检查单词拼写是否错误(支持英语)

Code Runner

  • 插件名:Code Runner
  • 功能:一键执行各种语言代码(常用于测试)

Debugger for Chrome

  • 插件名:Debugger for Chrome
  • 功能:在VSCode端,调试代码

Live ServerPP

  • 插件名:Live ServerPP
  • 功能:在服务器端打开你的文件,实时显示你修改的代码
    • 支持websocket 消息服务,可以用于调试websocket 客户端
    • 支持可编程虚拟文件,可用于模拟服务端API接口

Svg Preview

  • 插件名:Svg Preview
  • 功能:可以显示你的SVG图片,还可以编辑

Tabnine

  • 插件名:Tabnine
  • 功能:智能提示代码,可以预测你将要写的代码进行提示

Template String Converter

  • 插件名:Template String Converter
  • 功能:在字符串中输入$触发,将字符串转换为模板字符串

vscode-pigments

  • 插件名:vscode-pigments
  • 功能:实时预览设置的颜色

Parameter Hints

  • 插件名:Parameter Hints
  • 功能:提示函数的参数类型及消息

Quokka.js

  • 插件名:Quokka.js
  • 使用:安装插件后,ctrl+shift+p输入Quokka new JavaScr..即可使用
  • 功能:实时显示打印输出,更多功能自行探索(常用于测试)

Highlight Matching Tag

  • 插件名:Highlight Matching Tag
  • 功能:当光标停留在标签时,高亮匹配的标签

大众类插件

  • 基本都有安装就不详细介绍了

插件

  • Bookmarks
    • 功能:常用于读源码进行标记行,跳转(代码标记快速跳转)
  • ESLint
    • 功能:代码规范检查
  • Prettier - Code formatter
    • 功能:代码美化,自动格式化成规范格式
  • Project Manager
    • 功能:项目管理插件,当开发多个项目时,可以快速跳转
  • Path Intellisense
    • 功能:路径智能提示
  • Image preview
    • 功能:当引入路径为图片时,可以预览当前图片
  • GitLens
    • 功能:增强了git功能,支持在VSCode查看作者、修改时间等等
  • open in browser
    • 功能:在浏览器打开当前文件

Vue 开发推荐

vue-component

  • 插件名:vue-component
  • 功能:输入组件名称自动导入找到的组件,自动导入路径和组件
    • 选中后自动输入组件名(包含必填属性)、import语句、components属性

Vetur

  • 插件名:Vetur
  • 开发 Vue 必备

Vue 3 Snippets

  • 插件名:Vue 3 Snippets
  • 基本必备:很多Vue的代码段,很方便开发

React 开发推荐

React Style Helper

  • 插件名:React Style Helper
  • 功能:在React中更快速地编写内联样式,并对 CSS、LESS、SASS 等样式文件提供强大的辅助开发功能
    • 自动补全
    • 跳转至样式和变量定义位置
    • 创建 JSX/TSX 的行内样式
    • 预览样式及变量内容
  • 行内样式自动补全,同时支持 SASS 变量的跳转及预览。

ES7 Reactsnippets

  • 插件名:ES7 React/Redux/React-Native/JS snippets
  • 功能:很多React的代码段,很方便开发

vscode-styled-components

  • 插件名:vscode-styled-components
  • 功能:在JS文件中写样式时,有智能提示

主题类

Dracula Official

  • 插件名:vscode-styled-components

One Dark Pro

  • 插件名:One Dark Pro

vscode-icons

  • 插件名:vscode-icons
  • VSCode文件夹&文件图标

其他推荐

  • 以下插件,可能不常用,大家感兴趣可以试试😉

CSS Initial Value

  • 插件名:vscode-icons
  • 功能:显示每个CSS属性的初始值,当光标停留在css属性时

画板作图

  • 插件名:Draw.io Integration
  • 功能:在VSCode中画图,支持多人协作编辑图表..

Echars 智能提示插件

  • 插件名:echarts-vscode-extension
  • 使用:安装插件后,ctrl+shift+p输入active Echars即可开启智能提示
  • 功能:提示各种Echar中Option 的属性,挺强大的

翻译插件

  • 插件名:A-super-translate
  • 使用方法:选中行,Ctrl+Shift+p 输入 翻译
    • 键入 ctrl+`再按下 ctrl+1 为翻译直接替换选中区域
  • 功能:翻译识别代码中注释部分,不干扰阅读。支持不同语言,单行、多行注释、
    • 支持用户字符串与变量翻译,支持驼峰拆分

总结(附全部插件图片)

  • 根据需求,大家安装对应插件即可(安装太多插件,VSCode会很卡)
  • 当然电脑配置足够强大,当我没说🤔
Web前端号整理 From 风不识途

有人靠这份前端面试题涨薪到30K,字节版附答案!

本年度第一个求职和招聘高峰已经过去,有人顺利完成跳槽,涨薪开始迈向巅峰,有人还在前端基础苦苦挣扎,暗无天日的感觉。这一份前端面试题,有人靠着他直接从小白薪资直接涨到30K,简直是求职神器。这里全部奉上,包含html,css,js等前端基础,也包含网络协议(http)、浏览器和终端等计算机基础以及火热的vue框架,还包括一些高阶的数据结构和算法等,以字节跳动等大厂前端面试真题为主,几乎从广度和深度囊括了前端开发所涉及到的主要领域。

前端面试秘籍

神器在手,也得自己熟练使用才能仗剑杀敌,建功立业,希望大家好好利用这份整理的核心前端面试题,对照自己,查漏补缺,往外延展,把自己打造的更值钱。

开始:

HTML

  • HTML5 有哪些新特性?
  • Doctype作⽤? 严格模式与混杂模式如何区分?它们有何意义?
  • 如何实现浏览器内多个标签页之间的通信?
  • ⾏内元素有哪些?块级元素有哪些?空(void)元素有哪些?⾏内元 素和块级元素有什么区别?
  • 简述⼀下src与href的区别?
  • cookies,sessionStorage,localStorage 的区别?
  • HTML5 的离线储存的使用和原理?
  • 怎样处理 移动端 1px 被 渲染成 2px 问题?
  • 浏览器是如何渲染页面的?
  • iframe 的优缺点?
  • Canvas 和 SVG 图形的区别是什么?
  • 谈一谈meta 标签?

CSS 基础

  • 请你讲一讲 CSS 的权重和优先级
  • 介绍 Flex 布局,flex 是什么属性的缩写:
  • CSS 怎么画一个大小为父元素宽度一半的正方形?
  • CSS实现自适应正方形、等宽高比矩形
  • 实现两栏布局的方式
  • 实现三列布局的方式
  • CSS 动画有哪些?
  • 用css2和css3分别写一下垂直居中和水平居中
  • visibility 和 display 的差别(还有opacity)
  • opacity 可以有过渡效果嘛?
  • BFC 与 IFC 区别
  • BFC会与float元素相互覆盖吗?为什么?举例说明
  • 了解box-sizing吗?
  • 什么是 BFC
  • 了解盒模型吗?
  • 说一下你知道的position属性,都有啥特点?
  • 两个div上下排列,都设margin,有什么现象?
  • 清除浮动有哪些方法?

JavaScript 基础

  • 问:0.1 + 0.2 === 0.3 嘛?为什么?
  • JS 有哪些我数据类型?
  • JS 整数是怎么表示的?
  • Number() 的存储空间是多大?如果后台发送了一个超过最大自己的数字怎么办
  • 写代码:实现函数能够深度克隆基本类型
  • 事件流
  • 事件是如何实现的?
  • new 一个函数发生了什么
  • new 一个构造函数,如果函数返回 return {}return nullreturn 1return true 会发生什么情况?
  • symbol有什么用处
  • 闭包是什么?
  • 闭包产生的本质
  • 一般如何产生闭包
  • 闭包的应用场景
  • 什么是作用域?
  • 什么是作用域链?
  • NaN 是什么,用 typeof 会输出什么?
  • JS 隐式转换,显示转换
  • 了解 this 嘛,bind,call,apply 具体指什么
  • 手写 bind、apply、call
  • setTimeout(fn, 0)多久才执行,Event Loop
  • 手写题:Promise 原理
  • js脚本加载问题,async、defer问题
  • 如何判断一个对象是不是空对象?
  • <script src=’xxx’ ’xxx’/>外部js文件先加载还是onload先执行,为什么?
  • 怎么加事件监听
  • 事件传播机制(事件流)
  • 说一下原型链和原型链的继承吧
  • 说下对 JS 的了解吧
  • 数组能够调用的函数有哪些?
  • 如何判断数组类型
  • 函数中的arguments是数组吗?类数组转数组的方法了解一下?
  • 用过 TypeScript 吗?它的作用是什么?
  • PWA使用过吗?serviceWorker的使用原理是啥?
  • ES6 之前使用 prototype 实现继承
  • 如果一个构造函数,bind了一个对象,用这个构造函数创建出的实例会继承这个对象的属性吗?为什么?
  • 箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?
  • 知道 ES6 的 Class 嘛?Static 关键字有了解嘛
  • 事件循环机制 (Event Loop)
  • 手写题:数组扁平化
  • 手写题:实现柯里化
  • 手写题:数组去重
  • let 闭包
  • 变量提升
  • instance 如何使用
前端js面试题 字节版

Vue框架

  • active-class是哪个组件的属性?嵌套路由怎么定义?
  • 怎么定义vue-router的动态路由?怎么获取传过来的动态参数?
  • vue-router有哪几种导航钩子?
  • scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
  • mint-ui是什么?怎么使用?说出至少三个组件使用方法?
  • v-model是什么?怎么使用?vue中标签怎么绑定事件?
  • axios是什么?怎么使用?描述使用它实现登录功能的流程?
  • axios+tp5进阶中,调用axios.post(‘api/user’)是进行的什么操作?axios.put(‘api/user/8′)呢?
  • 什么是RESTful API?怎么使用?
  • vuex是什么?怎么使用?哪种功能场景使用它?
  • mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?
  • 自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?
  • 说出至少4种vue当中的指令和它的用法?
  • vue-router是什么?它有哪些组件?
  • 导航钩子有哪些?它们有哪些参数?
  • Vue的双向数据绑定原理是什么?
  • 请详细说下你对vue生命周期的理解?
  • 请说下封装 vue 组件的过程?
  • 你是怎么认识vuex的?
  • vue-loader是什么?使用它的用途有哪些?
  • 请说出vue.cli项目中src目录每个文件夹和文件的用法?
  • vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?
  • 聊聊你对Vue.js的template编译的理解?
  • Vuex是什么?为什么使用Vuex?
  • vuejs与angularjs的区别?
  • vue为什么不直接操作dom?
  • 你怎么理解vue是一个渐进式的框架?
  • Vue声明组件的state是用data方法,那为什么data是通过一个function来返回一个对象,而不是直接写一个对象呢?
  • 说下vue组件之间的通信?
  • vue中mixin与extend区别?
前端vue面试题 字节版

计算机网络基础

  • HTTP 缓存
  • HTTP 常用的状态码及使用场景?
  • 你知道 302 状态码是什么嘛?你平时浏览网页的过程中遇到过哪些 302 的场景?
  • HTTP 常用的请求方式,区别和用途?
  • 你对计算机网络的认识怎么样
  • HTTPS 是什么?具体流程
  • 三次握手和四次挥手
  • 在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?
  • 你对 TCP 滑动窗口有了解嘛?
  • WebSocket与Ajax的区别
  • 了解 WebSocket 嘛?
  • HTTP 如何实现长连接?在什么时候会超时?
  • Fetch API与传统Request的区别
  • POST一般可以发送什么类型的文件,数据处理的问题
  • TCP 如何保证有效传输及拥塞控制原理。
  • http知道嘛?哪一层的协议?(应用层)
  • OSI七层模型和TCP/IP四层模型
  • TCP 协议怎么保证可靠的,UDP 为什么不可靠?
  • HTTP 2 改进
  • DDOS 攻击
前端面试必知的计算机网络基础知识

算法

链表

  • 前序遍历判断回文链表
  • 反转链表
  • 合并K个升序链表
  • K 个一组翻转链表
  • 环形链表
  • 排序链表
  • 相交链表

字符串

  • 【面试真题】最长回文子串【双指针】
  • 最长公共前缀【双指针】
  • 无重复字符的最长子串【双指针】
  • 【面试真题】最小覆盖子串【滑动窗口】

数组问题

  • 【面试真题】俄罗斯套娃信封问题【排序+最长上升子序列】
  • 最长连续递增序列【快慢指针】
  • 最长连续序列 【哈希表】
  • 【面试真题】盛最多水的容器【哈希表】
  • 寻找两个正序数组的中位数【双指针】
  • 删除有序数组中的重复项【快慢指针】
  • 和为K的子数组【哈希表】
  • nSum问题【哈希表】
  • 【面试真题】接雨水【暴力+备忘录优化】
  • 跳跃游戏【贪心算法】

二叉树

  • 二叉树的最近公共祖先
  • 二叉搜索树中的搜索
  • 删除二叉搜索树中的节点
  • 完全二叉树的节点个数
  • 二叉树的锯齿形层序遍历

排序算法

  • 用最少数量的箭引爆气球
  • 合并区间【排序算法+区间问题】

二分查找

  • 判断子序列【二分查找】
  • 在排序数组中查找元素的第一个和最后一个位置【二分搜索】

动态规划

  • 最长递增子序列
  • 【面试真题】 零钱兑换
  • 【面试真题】 最长公共子序列
  • 编辑距离
  • 【面试真题】最长回文子序列
  • 【面试真题】最大子序和
  • 【面试真题】 买卖股票的最佳时机

BFS

  • 打开转盘锁
  • 二叉树的最小深度

  • 最小栈【栈】
  • 下一个更大元素
  • 【面试真题】有效的括号
  • 简化路径

DFS

  • 岛屿的最大面积
  • 相同的树

回溯算法

  • N皇后
  • 全排列
  • 括号生成
  • 复原 IP 地址
  • 子集
前端必懂的数据结构和算法 字节跳动面试真题

以上是这份秘籍的核心知识点和脉络,主要是字节跳动2020年和2021年的前端面试真题,也代表了当前互联网公司在面试时候的主要知识点。

哪些手机可以升级鸿蒙系统?什么时候可以升级?华为HarmonyOS 2升级计划来了

6月2日,万众瞩目的华为鸿蒙操作系统——HarmonyOS 2终于官宣问世。不是另一个安卓或者IOS, 而是一个迈向万物互联的全信的操作系统,不管后续发展如何,世界又多了一个选择,看起来还不错的选择。鸿蒙的发展和意义交给市场和时间,普通用户最关心的莫过于自己的手机是否能升级体验鸿蒙系统,尝尝鲜,以及什么时候可以升级,说实话我是有点迫不及待了。

鸿蒙操作系统——HarmonyOS 2

余承东在发布会会上宣布了鸿蒙系统的手机升级计划

华为Mate,Nova以及P系列,多个层次多种终端均可升级。

华为 Mate 9 系列、nova 5 系列、P10 系列、畅享 10 以后的机型、华为平板 M5 等机型将在明年升级鸿蒙 2 系统。

6 月 2 日起,首批启动公测升级 HarmonyOS 2 的设备包括:华为 Mate 40 系列、Mate 30 系列、P40 系列、Mate X2、MatePad Pro。

2021 年第 3 季度计划升级华为 Mate Xs、Mate 20 系列、nova 8 系列、nova 7 系列、nova 6 系列、MatePad 等。

2021 年第 4 季度,计划升级华为智慧屏 V 系列 2021 款、智慧屏 S 系列、智慧屏 X65、Mate 20 X、P30 系列、Mate X 等。

2022 年上半年,计划升级华为 Mate 10 系列、P20 系列、Mate 9 系列、P10 系列等,具体清单和适配时间请关注官方公布信息。

已经出走的荣耀手机可以升级鸿蒙系统吗?

好消息:HarmonyOS 官方今晚宣布了百机升级机型详情,其中就包括众多荣耀手机。

荣耀手机的鸿蒙升级时间会在2021年第四季度开始。

2021 年 Q4 将升级荣耀 30 Pro、荣耀 30 Pro+、荣耀 V30、荣耀 V30 PRO、荣耀 30、荣耀 30S、荣耀 V20、荣耀 V20 MOSCHINO 联名版、荣耀 Magic 2、荣耀 20、荣耀 20 PRO、荣耀 X10 MAX、荣耀 X10、荣耀平板 6、荣耀平板 X6、荣耀 Play4 Pro、荣耀 30 青春版、荣耀 Play4。

2022 年 H1 起,将升级荣耀 V10、荣耀 10、荣耀 Play、荣耀 20S、荣耀 Play4T Pro、荣耀 9X、荣耀 9X PRO、荣耀 8X、荣耀 10 青春版、荣耀 20i、荣耀 20 青春版、荣耀 9、荣耀 V9、荣耀 play 3、荣耀平板 5 8 英寸、荣耀 Note10、荣耀平板 5 10.1 英寸。

华为鸿蒙系统harmony os2 升级计划时间表
华为鸿蒙系统Harmony OS 2升级计划

手机升级到鸿蒙系统后不好用,可以回到原来的系统吗?

答案是可以,具体操作,下次在喽喽。

好了,大家做好鸿蒙测试员,一起为国产软件加油吧!

谷歌正式发布Fuchsia OS操作系统,在鸿蒙即将官宣的时刻

华为鸿蒙OS- Google Fuchsia OS

沉寂了数年之久的Fuchsia OS,近日迎来了5年来最重要的时刻,曾经引起巨大轰动的Fuchsia OS正式发布,即将迈入大规模的实际场景应用。而另一边,万众瞩目的华为本土操作系统——鸿蒙,也将在6月2日正式官宣。这两个苹果IOS之外的两个最被关注的系统,一个被视为未来的安卓,一个被视为安卓之外的新选择,都很大程度决定这两个科技巨擘的未来。而发布的时间如此接近,还真有点枕巾对麦芒的味道。

谷歌Fuchsia OS正式开始接入智能设备

9to5Google 报道,谷歌已经向其确认,Fuchsia OS 将向 2018 年发布的初代 Nest Hub 智能显示器推出。更新后的 Nest Hub 将不会有功能改变,但系统底层将由基于 Linux 的 Cast OS 变更为 Fuchsia OS。

谷歌 Fuchsia OS 项目技术负责人 Petr Hosek 在推特上庆祝了新平台的发布:“今天是个重要的日子,我们发布新操作系统啦!”

New OS-Google Fuchsia OS

Nest Hub 基于 Fuchsia OS 的更新会在未来几个月内陆续推出,考虑到界面和体验将保持不变,用户可能不会有直接的感知。自 2016 年以来 Fuchsia 的发展一直备受关注,从实验性的用户界面开始,一直到运行至一些内部测试设备,包括谷歌智能家居和 Chromebook 系列的全部产品。如今,谷歌宣布将在几个月内为初代 Nest Hub 智能显示器用户推送 Fuchsia OS,这表明它已经准备好在个人设备上提供服务。

Google Fuchsia OS on Nest Hub

不过,Fuchsia 不只是智能显示操作系统。彭博社(Bloomberg)于 2018 年发布的一份报告迄今都完全命中 Fuchsia 的发布计划,其中提到谷歌希望“在三年之内”首先在联网的家用设备上发布该操作系统。该报告还指出了 Fuchsia 的下一步措施,包括计划在 2023 年大规模扩张到智能手机和笔记本电脑。

谷歌在 Fuchsia OS 上投入了数百人,经过五年多的发展,Fuchsia OS 已经开始引起其他行业巨头的关注。最近,三星开始与谷歌合作开发该项目。很多人猜测 Fuchsia OS 未来可能会全面取代 Android 与 Chrome OS,而三星可能会成为最先抛弃 Android 改用 Fuchsia OS 的手机厂商。

谷歌 Fuchsia OS 是什么?

Fuchsia 是一套全新的操作系统,其项目定位一直在发展变化。

作为一套新的操作系统,Fuchsia 最初于 2016 年首次亮相于谷歌代码库与 GitHub,该项目完全开源:https://fuchsia.googlesource.com/。更重要的是,Fuchsia 并非基于 Linux 内核,而 Linux 内核又恰恰是 Android(谷歌打造的移动操作系统)与 Chrome OS(谷歌台式机与笔记本电脑操作)的核心基础。很明显,Fuchsia 承载着谷歌更大的野心。

谷歌 Android 工程副总裁 Dave Burke 在 2017 年接受采访时如何介绍 Fuchsia:“Fuchsia 是一个早期实验项目。大家可能都知道,我们在谷歌筹划过不少非常酷炫的早期项目。我认为最有趣的点在于 Fuchsia 直接开源,每个人都可以查看成果并做出评论。与其他早期项目一样,Fuchsia 也会不断发展变化。”

时间到了 2018 年,Fuchsia 开发者 Travis Geiselbrecht 通过公共 Fuchsia IRC 频道强调,这套操作系统绝不是“玩具”,于是情况变得更加扑朔迷离。他证实称,Fuchsia 的开发进度已经颇为可观,而且参与其中的谷歌开发人员可以随意进行兴趣化探索。在他看来,Fuchsia“绝不是那种用掉就丢的垃圾项目。”

之后的两年 Fuchsia 蜇伏了起来,直到 2020 年谷歌再次推动宣传,希望通过平台开放为其吸引更多软件开发支持者。2021 年初,先是项目的 F1 分支,之后又有 F3 分支,随着一个个重要代码开发步骤的落地,Fuchsia 的面貌及发展方向也开始愈发清晰,事实证明这套操作系统已经达到了一系列重要发展里程碑。

谷歌 Fuchsia OS 的将会用来做什么,用在哪里?

Fuchsia 只是一套内核。谷歌可能想用 Fuchsia 证明自己对未来的探索。

与基于 Linux 的 Android 或 Chrome OS 不同,Fuchsia 基于 Zircon(原名 Magenta)构建而成。该内核开始时使用的是 C ++ 代码,为了实现其安全目标,现在正朝着 Rust 发展(现在已经达到 50%)。一年前谷歌还向 Fuchsia 添加了对 Swift 的支持。

目前比较流行的观点是,Fuchsia 应该代表一款新型操作系统,未来用于将 Chrome OS 与 Android 统一在同一套系统之下(自 2015 年以来始终存在此类传闻)。但根据最近浮出水面的说明文档、代码以及 UI 来看,这套操作系统好像并不是 Android 与 Chrome OS 的融合体、甚至不属于任何完整操作系统。目前,它还只是个内核项目——也就是操作系统的核心所在。

谷歌公司在内部文档中指出,Fuchsia 主要面向采用“高速处理器”加“低内存容量”的“现代手机与个人计算机平台”。文档还明确提到,“Fuchsia 不是 Linux”。Fuchsia 的 GitHub 页面上出现了两位顶尖嵌入式系统开发者的姓名,一位是谷歌高级软件工程师、另一位则是前 Android TV 与 Nexus Q 项目工程师。

此外,卡片化设计的早期用户界面 Armadillo 内置于谷歌的 Flutter SDK 之内,而后者专门用于创建可在多种设备及操作系统上运行的跨平台代码。使用 Armadillo,用户可以随意拖动不同卡片实现屏幕拆分、或者在选项卡式界面中使用。

同时,Fuchsia OS 的核心独立于硬件规格,使用模块化方法,这意味着它将不再是一大堆代码,而是将其分割成多个构建块或“包”,制造商能够根据设备选择 Fuchsia 的功能。

Fuchsia OS 模块化

Fuchsia OS 中的模块化

Fuchsia 的模块化框架带来的另一个优势是,它可能仅通过安装更新的组件就可以添加新功能。从实际出发,模块化不仅可以解决系统更新时可能出现 Bug 的问题,而且还可以加快应用程序的更新速度。这种模块化方法对于 Fuchsia 所提供的统一体验至关重要。

因此有猜测,未来我们可能会看到 Fuchsia 与其他新兴技术融合在一起,发展成为一个集合的、相互连接的设备系统,这样操作系统就不会单独运行在每个设备上。取而代之的是,可以在每个设备上以分散化的实例形式运行这个无所不包的 OS,所有这些实例都可以协同工作。

谷歌 Fuchsia OS 是否会取代 Android?

新系统确实能解决 Android 中的不少问题。但 Android 已经全面铺开,何必重新发明轮子?

Android 最初是为带有 QWERTY 键盘的智能手机设计的,后来逐渐适配触摸屏控制。并且有说法是 Android 在设计时并未考虑虚拟现实或增强现实。鉴于它已经有十年历史了,因此如果谷歌希望应对下一个十年的挑战,那么比起修改 Android 代码,也许重新开始设计一个新操作系统才是更好的办法。

Android 本身的碎片化问题仍然很严重,根源当然是几十家手机制造商推出的数百款设备都在使用不同的自定义 Android 版本。另外,由于 Android 系统为开源项目,所以在更新方面也有不少冲突。谷歌为 Android 制定了年度更新发布时间表,但要真正向整个生态系统推开还需要一段时间。

目前,谷歌仍然只能将 Android 新版本交付给 OEM 厂商和电信运营商,再由他们安装并加载至目标硬件上,这种无法由谷歌直接控制的体系必然导致碎片化加剧。另外,Android 还基于 Linux 内核,而后者目前不仅面临诸多法律问题的困扰,而且内核还经历了一番全面调整,极大提升了出现 bug 及安全漏洞的可能性。

也许一套全新操作系统平台能帮助谷歌解决以上所有问题,同时也将有效回避昂贵的专利许可成本。由于从零开始构建而成,这套现代化操作系统将更安全、更可靠且优化度更高。另外,新系统既可以采用模块化设计、也可以强调统一性,保证更全面地覆盖各类设备。但无论如何展望,我们都需要回答最核心的灵魂拷问:Android 已经全面铺开,何必还要重新发明轮子?

华为鸿蒙OS宣布将于6月2日正式发布

谷歌很早之前就封禁了华为设备,导致华为海外欧美市场急剧下滑,华为也因此从世界第一跌落神坛。

鸿蒙系统的推出是无奈,是一种反击,也包含着华为的野心和决心。

宣布将于62日晚8召开鸿蒙操作系统及华为全场景新品发布会,届时会发布鸿蒙OS正式版。

  按照近期进行开发者测试的用户反馈来看,鸿蒙OS目前已经非常完善,稳定性和性能都十分出色,与基于安卓的EMUI相比也毫不逊色,还能带来一些此前在安卓无法实现的功能。

  据悉,目前华为正在与全球排名前200的App厂商沟通合作,共同开发跨终端设备的应用。华为公司预计,2021年底搭载鸿蒙操作系统的设备数量将达3亿台,其中华为设备超过2亿台,面向第三方合作伙伴的各类终端设备数量超过1亿台。此外,鸿蒙系统也向第三方手机厂商开源

谷歌Fuchsia OS 和华为鸿蒙谁将赢得未来?

  而华为在最初研发鸿蒙系统的时候就有很大的野心,鸿蒙系统不仅仅是针对手机推出的操作系统,鸿蒙OS还将打通电脑、平板、智慧屏、手表、车机等设备,是布局IoT、汽车领域的重要一环。 

一个被认为全新的安卓,一个被视为全新的系统,这场事关生死的博弈,谷歌Fuchsia OS 和华为鸿蒙谁将赢得未来?

2021年阿里淘宝前端最新面试题汇总

一年之计在于春,正所谓金三银四,过完年是求职高峰期,也是企业招人高峰期。前端开发工程师看过来,2021年阿里巴巴集团淘宝网最新前端开发面试题来了,想去淘宝的赶紧收藏行动起来。

第一部分:淘宝网 HTML & CSS 面试题 
1 .Doctype 严格模式与混杂模式,如何可触发这两种模式,区分它们有何意义? 
2 .行内元素有哪些?块级元素有哪些? CSS 的盒模型? 
3 . CSS 引入的方式有哪些 link 和@import 有什么区别?
4 . CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联样式和imortant哪个优先级高? 
5 .前端页面有哪三层构成,分别是什么?作用剥十么? 
6 . CSS的基本语句构成是? 
7 .你做的页面在哪些浏览器测试过?
     这些浏览器的内核分别是什么?
     经常遇到的浏览器的兼容性有哪些?怎么会出现?解决方法是什么? 
8 .如何居中一个浮动元素? 
9 .有没有关注 HTML5 和 CSS3?如有请简单说-些您对它们的了解情况! 
10 .你怎么来实现下面这个设计图,主要讲述思路(效果图省络) 
11 .如果让你来制作-个访问量很高的大型网站,你会如何来管理所有 CSS 文件、 JS 与图片? 
12 .你对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?

第二部分: 淘宝网Javascript 面试题 
1 . js 到十么,js和 html的开发如何结合? 
2 .怎样添加、移除、移动、复制、创建和查找节点?

以上是淘宝网的前端面试题的汇总,技术性面试中,一定要把自己的技术实力体现出来,表达出来,会的要好好讲,不会的就大胆的说不会,不要不懂装懂,班门弄斧,同时要体现自己愿意学习的态度和能力。

希望大家新年找工作顺利!

快过年了,用JS放个烟花吧

前端工程师的绽放时刻来了。

快过年了,现在全国大部分地区都禁止燃放烟花,而工程师们大部分也在cold的冬夜里不停的code,code,code…,想看个烟花简直难上加难。

但是,没有什么是能够难住工程师的,尤其是前端工程师,不就是用js放个烟花,安排。

如何实现用js放烟花?

第一步:先创建一个Canvas;

第二步:分析烟花的运动轨迹;

第三步:初步实现动效

第四步:优化,让烟花更逼真

第五步:兼容任意网页可绽放

js实现烟花绽放效果

具体的细节请参考 大帅搞前端 的微功号

代码我替大家扒下来了:https://codepen.io/jackrugile/pen/acAgx

希望对大家有用。

web前端号:持续挖掘有用的前端干货!

抢不到票?不存在的。一个前端工程师用node写了个抢票软件,还能自动提醒

临近春节,在外胆战心惊奋斗一年的我们终于要准备回家了。但再远的距离都敌不过一张火车票的距离。一年一度的春运即将上演,抢票大战正在激烈进行,今年你抢到票了吗?

对互联网从业人员来说,抢票具有天然的优势。不仅可以时时刻刻盯盘,而且主要互联网是工程师的地盘,有主场作战的优势,相当惬意。对工程师来说,抢不到票是不存在的,如果抢不到,那他就写一个程序。这就有这么一个前端狗,自己动手用node.js 写了一个辅助抢票程序,还能设置短信提醒,可以说是捡漏神器。

下面来看看这个前端工程师是如何用node js 写出这个软件的。主要的步骤有:

获取接口信息、Node.js 请求目标接口、开发通知功能。

具体的步骤有:

node js开发抢票和提醒功能

该软件引来众人围观

node js 开发抢票和短信提醒功能案例

受限于版权,更具体的开发教程请查看掘金网 西岚。

说明:仅用于学习研究,切勿大量使用

Web前端号: 持续挖掘有用的前端知识

展望2021年Web前端开发的七大趋势

前端开发技术不断更新和丰富,能做的事情也是越来越多,2021年web前端开发将继续飞速发展。新年伊始,我们来展望一下2021年web前端开发的七大趋势,希望对大家的学习和职场有助帮助。

网站不仅仅是代码的组合,传播上来说,你的网站是用户关于你的第一印象,在与其互动的过程形成的印象,对企业品牌都有着潜移默化的影响。现在的网站开发工作不只是代码搬运工,而是变得越来越具有创造性。同时市场上的新趋势不断影响着 Web 开发流程,为开发人员设计和构建网站带来了更多灵活和实用的方式。

2021年web前端开发的7大趋势
2021年web前端开发的7大趋势

渐进式 Web 应用开发(PWA)

PWA 看起来很像原生移动应用程序,但它实际上是一种网站。根据研究,PWA 的转换率比原生应用高 36%;因此,我们可以看到它的发展势头日趋明显。PWA 的主要目标是为使用各种类型设备的用户都带来类似移动应用的体验。

它们更具互动性和响应能力。PWA 正在变革用户体验,因为它的功能类似原生应用,却无需用户下载。一些业内知名企业,例如 Amazon、Twitter 和 Forbes,正在将原生和 Web 应用程序结合起来以增加转化率并降低流失率。由于 PWA 的脱机工作机制、快速加载和页面速度,越来越多的全球化企业正在使用它来加强品牌影响力。

由于 PWA 的可访问性和可靠性优势,这种应用的用户规模在持续增长,成为 2021 年的重要趋势。

深色主题 UI

我们已经在移动应用程序中看到了这种趋势,现在网站也正在朝着这一方向发展。夜晚或黑暗主题的用户界面对眼睛来说更安全、浏览起来更轻松。它不仅减少了过度的眼疲劳现象,而且还增强了对比度,使用户更容易看到浅色内容。这种主题还延长了设备续航时间,因为在 OLED 屏幕上,更多的黑色像素会消耗更少的电力。此外,它还为整个网站带来了相当时尚的风格,并提供最佳的用户体验。

这是 2021 年 Web 开发领域的流行趋势之一。行业头部品牌,如 WhatsApp、Facebook、Twitter、Android、Apple、YouTube、Reddit 等,都已经投身于这一潮流之中。

人工智能驱动的聊天机器人

在 2021 年,对基于 AI 的沟通交流需求将不断增长。网站将投入更多资源来构建基于 AI 技术的聊天机器人和虚拟助手,以改善客户体验。

聊天机器人可能收获的风评不是很好,但它们确实很方便。用户访问网页时,页面上的聊天机器人可以立即与他们建立联系。它们为用户提供了快速的响应,这可以帮助企业避免服务延误,降低客户流失率。

聊天机器人可以从同用户的交流中收集数据,并基于这些数据进行训练和改进,进而提供更好的解决方案。此外,它们使用自然语言编程技术来与人类更加自然地互动。

语音识别技术和认知智能相结合,使聊天机器人可以做到比人工支持人员更高的可靠性。在全球范围内,电子商务、旅行和旅游业、医疗保健等行业正在快速意识到聊天机器人的重要性。

单页网站

这种趋势在 2020 年已经非常明显了,在 2021 年也将一直持续下去。

构建复杂而全面的 Web 结构的时代已经一去不复返了。随着人们普遍习惯通过移动设备接入互联网,单页网站凭借更易浏览的优势大行其道,为不同主题构建单独页面的旧方法已然过时。

单页网站极大地减少了页面加载需求,并加快了页面响应速度,从而降低了流失率。由于其简单性,它在移动设备和台式机上均有很好的表现。而且,它的开发和托管工作并不昂贵。单页网站可以帮助企业用有限的内容吸引特定的目标受众。此外,它的简约设计更易阅读、更具吸引力。

语音识别技术

物联网(IoT)走上前台已经有一段时间了。在 2021 年,我们可以看到或期望在一个重要领域看到显著的进步,那就是语音识别。根据研究,到 2023 年预计将有 80 亿个语音助手投入使用。

语音搜索功能的应用将极大地影响开发人员的工作方式。基于语音的电子商务有望主导市场。像 Google、Amazon、Microsoft 等公司都在使用这项技术来开发创新产品和服务。

此外,随着智能扬声器和助手的问世,语音识别技术已经达到了一个全新的发展水平。因此,开发人员需要充分优化网站来增强语音搜索功能。

云计算

根据 Gartner 的数据,到 2021 年,公共云服务市场预计将增长到 3069 亿美元。云计算在 2021 年的前景是可以预见的。

云计算可预防数据丢失和数据过载。因此它具有替换常规服务器的能力。这种趋势将在未来几年内改变 Web 开发的方式,因为它不仅可以降低开发成本,而且可以增强整个 Web 架构。Google Cloud Functions、Azure Functions、AWS Lambda 等服务都是流行的云计算示例。

考虑到当前的全球形势,许多企业都依赖远程解决方案。这些 Web 开发趋势可以帮助企业构建无缝的工具。Angular.Js、Node.Js 等框架将在 2021 年继续得到高度关注,直到有更好的技术取代它们。AR/VR、物联网、motion UI、高性能移动页面和区块链技术的进化也将持续。

网站安全性

安全,是一个在任何时候都不能忽略的问题。根据研究,每天有将近 50,000 个网站被黑客攻破。这是一个令人担忧的数字,因为有太多的公司正在使用数字平台来运营自己的业务。另一方面,网站上还经常包含许多敏感的客户信息。2021 年,很多严格的网站安全协议将开始普及,提升网站的合规水平。

改用 HTTPS 协议将是所有网站开发人员和所有者的首要任务。HTTPS 协议是所有网站的基础安全标准,它可以确保通信的安全性,不会受到第三方的任何威胁。Google 已将不受 HTTPS 保护的网站标记为不安全。

定期更新软件对于确保网站安全性而言至关重要。行业还将普遍采用有效的密码管理解决方案。

据统计,全球已有超过 17亿个网站。这意味着,几乎在每一个细分领域都有无数网站在进行着激烈的竞争。开发人员应该了解和发现更多创新的 Web 开发方式,并通过这些方法可以提升企业网站在搜索引擎上的排名,增加企业的曝光和流量,促进企业业务的发展。毕竟帮老板挣到钱,工程师才有福利鸭。

2021年加油

前端学着学着就迷茫了,越来越吃力?大神前端学习方法带你突破

前端不仅知识广,而且近几年又向纵深发展,难度也随之上升。总结起来就是前端越来越有用了,也越来越难了。不少想学习前端的小伙伴在学习了一段时间后,感觉前端越学越迷茫,越学越吃力,有很大的挫败感,这很可能是前端学习方法出了问题,这里总结一位一线前端大神(职场项目实践大神)的学习经验,希望对大家学习有所启发。

大神简介:工作两年多,已熟练掌握大部分前端原理、框架。工作上已经几乎没有解决不了的问题(除了那种跟着手机壳变换颜色的奇葩需求),成功超越老员工,被安排去面试(虐待)新人。

一、基础三大件要扎实

HTML、CSS、JavaScript 老三样必须完全掌握。不懂得建议直接查 MDN。

HTML重点掌握语义化。区分块级和内联标签。还有就是定义 head 里面一些meta 了解下。其他用到查文档,然后在实践中用熟悉就好了。

CSS。重点看盒子模型,定位,层级,过渡,动画和 transform。知道原理和规则。大部分工作都是照着设计稿化。掌握上面几个99%还原也不难。接下来重点学习几种常见的布局。完了之后去搞flex。最后搞下sass、less。基本就差不多了。

JavaScript。JS是重点和难点,红宝书看一遍掌握基础,进阶去看《你不知道的 JavaScript》。就这两套足够了,别搞那么多。争取每个知识点搞懂,后续ES6也就基本没啥问题了。下面几个问题必须拿下,优先级如下:

  1. this 用法,相关原理
  2. 原型/原型链
  3. 闭包
  4. 面向对象相关
  5. 同步异步/回调/promise/async、await
  6. 模块化 CommonJS, AMD

先搞这懂这些比较难的概念,对你JS理解更加深入。接下来在开始看框架方面

二、框架

前期要会用,后期要懂原理。

新人先搞 Vue。Vue 算是比较简单的框架了,上手容易。照着官方文档来问题不大。原理方面要提高自己认识。学习怎么看源码。github常去逛逛。

学习框架之前,我其实特别建议,新人先去了解 Babel 和 webpack 不仅仅是使用。一些原理方面的东西工作中也会用到。babel 里面会有教你如何编译代码。webpack教你如和打包文件。自己手写编译器和打包工具也不是特别难。反正对之后看vue、react源码帮助挺大。

搞完 Vue 全家桶,去了解下 React,React hooks 学习下新的理念。再回过头来看Vue。你会发现他们是如此的相似去又不同。

多去实践总结,对整体框架理解会越来越深刻。

今天先马到这里。想写的太多,马上就要上班下次有空再来码…

三、学会看源码

新人刚开始看源码,会陷入两个困境中。一是无从下手。二是看了之后感觉没啥收获。

这个也很正常。一般我们熟知的框架都有个几千甚至上万个PR。太大细节会干扰你。掌握整个节奏和流程。学习原理也比较吃力。就连找个入口都像大海捞针一样。建议从下面几个方面入手:

  1. 挑简单的上手。别一开始就搞 vue、react、webpack。太难,会直接劝退新人。不要为了面试而去读。反而效果不好,面试稍微问深入一点就答不出来了。平时有兴趣多琢磨琢磨。按照难易程度,函数库 < 组件库 < 框架 < 工程化 分别典型代表 lodash < vant < vue < webpack
  2. 手撸简易模型。像vue, webpack, babel 都有简易项目给你撸。有的创始人(尤哥)还直播手撸。国外的更多,youtube 一搜一大堆。就算不看源码,照着写出了简易 demo 对原理和理解提升都是很大的。
  3. 调试开源项目。先把项目拉下来。在vscode里面跑下,核心函数多打几个断点。看看里面变量是怎么diff的。对理解更深刻了。

看了源码是别人的,学到了是自己的。学习时候边记笔记,边思考原理,总结经验。下面来谈谈前端工程化怎么弄。

四、前端工程化

现在最流行的打包工具 webpack 用起来。当然直接用 vue-cli2、vue-cli3、create-react 都是可以的。但是 webpack 相关还是得掌握。

首先重点搞下babel、webpack。学习下编译,打包的原理。自己配置下 webpack。尝试自己去写下下 webpack 的 loader 和 plugin。学习这些之前要懂一点 node.js, node.js 不需要全部学习。一般就日常用到读写文件fs接口,path 路径接口。这些 api 都不难写几个 demo 就懂了。基本上webpack 里面配置文件也没用到多少 node 的东西。最后自己学会配置webpack的配置文件。

如果想深想去优化打包体积和速度,就需要去了解很多webpack插件。webpack 里面最核心的就是插件了。

当然前端工程化不仅仅是这些,CI/CD可持续集成, Umi 了解下。shell各种脚本自动化命令、代码生成技术了解下。

五、性能优化

一般来说。性能优化没什么系统化的文档供人学习。完全靠一些经验和自己的实践。

我们常提到性能好坏是由什么来衡量呢?

访问页面地址 –> 页面首次加载数据 –> 渲染出完整页面的时长

非首次情况下,命中缓存的加载缓存数据 –> 渲染出完整页面的时长。

一般我从下面几个方面着手去做,一般问题都不大。

减小资源(静态资源,后端加载的数据)大小

  • 压缩代码HTML/CSS/JS
  • 压缩图片、音视频大小
  • Tree-Sharking 消除无用代码

以上webpack都可以搞定

避免同一时间的过多次数请求

  • CSS 实现雪碧图:使用background-position共享一张图
  • 图片懒加载:监听滚动后offsetTop,  使用src 替换 src(真实路径)
  • 列表懒加载(分批加载):监听滚动后offsetTop, 发送请求加载下一页的数据
  • 路由懒加载
  • 代码分包分块加载(webpack)
  • 预加载技术
  • 小程序分包、预下载等。

利用缓存(空间换时间)

  • CDN 内容分发:获取更近网络节点缓存下来的静态资源
  • 浏览器缓存(自带)
  • 部分资源保存在LocalStorage或者APP缓存中(手动操作)

其他

  • SSR 服务端渲染:解决SPA框架带来JS动态渲染页面带来的延迟和白屏问题。

这些都可以去实践的,难度不大。难度大的地方可能是 dom 节点成千上万的时候渲染的性能问题。这个场景遇到的很少,方案很多。不同人有不同解决方案,有功夫可以自己去尝试尝试。

上面提到很多点都可以深入到很深。由于篇幅原因,点到即止。

纯粹是把一些我以前走过的弯路掰直了再分享给大家。毕竟不是《前端入门到精通》哈哈哈

六、移动端web开发

前端现在为什么这么火?各个公司都还挺缺优秀的前端。原因在于技术红利

移动端web流行起来之后,特别是H5和小程序,带动了多少前端就业,前端迅速取代了安卓和iOS 的大量岗位。

回到正题:所以作为前端人,移动web一般是都要接触的。不同于PC 端。

移动端有哪些东西呢? 不需要全部懂,差不多知道就行了。要用的时候再去学。

  1. 绝对单位换相对单位:px => rem / vw / rpx
  2. 弹性布局:使用flex、grid布局
  3. hairline (1px的粗线处理):使用伪元素 + transform: scale(倍数) 缩放线框
  4. WebView 环境了解下
  5. 安卓iOS 兼容踩坑:点击延迟、穿透、滚动不流畅、安全区域等等。
  6. 小程序开发相关踩坑
  7. JSBridge: H5 与App 通信
  8. H5动画制作
  9. 跨平台框架:react native、weex、flutter 等等

简单的说移动web 就是:html/css/js 跑在手机app 里面的WebView(web运行环境)。

小程序/公众号就是在这个基础上,将自己APP里面的WebView 租售给其他人使用。

微信APP —– 提供SDK —-> 微信webview —– 提供运行环境—–> 公众号h5 / 小程序

为什么微信可以容纳几乎无限的H5/小程序页面呢?

因为公众号/小程序的代码都存储在云端,通过不同的路由就可以给几乎无数的开发者使用。

使得微信成为一个运行环境+入口的存在。

七、做前端越学越觉得吃力?

前端入门比较简单,刚做时前端不吃力。因为我是软件工程专业,学前端之前,学过 C/C++、Java、PHP、.net 成绩还不错基本都是90多分。感觉自己干后端也不吃力。实验室里面的项目都是前后都写。最爱 PHP,当时最崇拜鸟哥。本以为以后就走上PHP后端工程师的道路了,成为鸟哥那样的大神。

由于项目需要的原因,后来渐渐开始学起学 HTML、CSS、JavaScript 这些语法相关的东西。刚接触时没有感觉太大难度。

当时就想着怎么把页面搞好看,搞各种动画炫技。写一个小球从下面弹出来的效果,换各种姿势弹出。当时觉得前端真的有意思,就入了前端的坑。入坑前,以为前端就是搞各种漂亮的页面,各种特性惊艳别人。

随着接触的越来越深。接触到了 AJAX, jQuery ,Bootstrap,前端开始注重体验。各种框架横空出世 backbone => Angular => React => Vue 眼花缭乱。

折腾了 JQuery 开始折腾 backbone 觉得前端还能这样玩。有些迷茫了,感觉脑袋快要炸了,那段时间特别焦虑,疯狂看书写代码,怎么这么多东西要学啊。

JavaScript 也不精通,到原型就不理解了,虽然有C++,JAVA面向对象的知识,但JavaScript 你怎么和别人玩的不是一个套路啊。当时就都用ES6了, 行,学。都用Sass了,行,学。不学也可以,看不懂别人的代码呀。

毕业前为准备校招前端工程师,真的很吃力。就怕校招面试时,自己啥都不懂。

功夫不负有心人,校招时候顺利拿到了自己满意的Offer。记得当时和面试官对答入流,好像找到知音一样。面试官也是过来人,基本能问的都问了。

拿到Offer之后就去了实习。实习第一个任务:将一个ES6的后台管理系统重构成 Vue2.0 全家桶的项目。有个导师带,但是她和我是不同项目,出了架构以外代码都是自己写。

这个阶段还是收获了很多:

  1. git 命令特别熟练。commit、stash、merge/rebase、cherry-pick、push/pull/fetch、reset等等基本都敲都特别多了
  2. 严格了代码规范。Eslint、prettier 都用起来了
  3. 会自己写业务组件,会封装高级组件、写常规页面了。基本上大部分不是特别复杂的交互都ok。难一点多找下资料可以做出来。
  4. 学会管理API了。自己尝试封装了 axios。统一处理错误和弹窗。
  5. 会抽取公共css、JavaScript 函数,编写CSS 变量和JavaScript 常量了
  6. webpack 能看懂配置文件了。

实习过后顺利转正。转正之后,换了另外一个导师带,加入到项目组作为一个比较大的项目的核心开发。基本不再做管理系统了。主要做一个saas 平台。涉及比较难的富文本编辑,UI 拖拽生产文章,数据可视化生产报表等等。还写了几个谷歌浏览器插件。

  1. 开始提升写页面效率,写的比较快了。
  2. 研究 webpack 的插件打包编译效率
  3. 研究 babel 编译原理
  4. 研究了 Vue 编译的一些原理
  5. 研究了 一些图表的使用,多半使用的echart。常规图表基本都用过。
  6. CI & CD 自己去搭建。学了一些 shell 脚本开发。研究了 docker 相关的东西。
  7. 尝试去写基础组件,搭建基础组件库。
  8. 学习 React 相关的语法。
  9. 研究富文本编辑,图片压缩裁剪原理等等
  10. 写一个简单的微信公众号,接触到了 H5 开发。

工作第一年,基本上主战场在PC 端。前半年挺吃力,后半年熟练后比较从容。会怼产品,喷设计,会和后端兄弟配合默契。和团队感情也很深了。

无奈项目由于某些原因终止,团队解散,调到新团队。在老东家工作一年多后,由于个人原因离开去了一家新的的公司,主战场从PC 到了手机。开始接触移动H5、hybrid 开发。

八、学习吃力的原因肯定是学习方法有问题。总结下一般怎么才能真正学到东西

  1. 详略得当:前端知识太多,抓重点学,不要像背字典一样。
  2. 不要急着写代码,先理清流程(以一个函数为单位,可以先写注释)再写代码。
  3. 看视频看讲解是会误以为自己会了,其实并没有。
  4. 学会总结:一句话可以讲清楚的事情,不要多说一句。减少心智负担。
  5. 不介意复制代码,但是要知道这个代码里面大致实现原理。感兴趣自己重写一个。
  6. 较大的项目,不要急着看代码。可以先把项目跑起来。通过改代码里面的参数来理解里面的核心流程。
  7. demo 式编程。对于新框架,参考demo来上手更快更容易理解。
  8. 渐进式编程。对于比较复杂的功能/需求。不要想着一气呵成。先实现一个核心,每次往上面加细节,有点像绘画。
  9. 断点单步调试很有用,定位bug会更快。当然有些不易调试的应用选择打log。一次打 log 要多打点,免得打完log,有得再加。
  10. 黑盒太多的项目,实在找不到bug原因。发给同事帮忙看。可能很快就能看出来。当局者迷,旁观者清。(很多时候是拼写的问题)

以上是这位前端大神带来的分享,希望他的前端学习方法和学习路径有助于还在前端爬坡的前端工程师们。

如果觉得有用,也请大家分享给更多志同道合的同学,一起加油!

如何构建高质量的前端工程项目?除了代码,团队运作机制非常重要

本文主要探讨在前端项目中,尤其是大型前端项目中,什么是高质量的前端工程项目?如何构建高质量的前端工程?以及用木桶理论来解释为什么除了代码,前端工程师团队的运作机制对前端工程代码的整体质量至关重要。

很长一段时间,大部分人都会认为前端代码的水平大多与工程师的能力水平有直接关系。这个是最直观的认识,尤其是在一些规模较小的工程项目中,这种相关性表现的更加明显。但是在大型的前端项目中,尤其是涉及多人协作的大型前端项目,仅仅依靠提升工程师能力水平,并不能直接提升整体项目的代码质量。除了代码本身的提高,合理的代码约束与正确的团队运转机制可能更为重要。

什么才是高质量的前端工程代码?

性能最优,技术最新,复用性最强的技术选型就是高质量的前端工程代码吗?回顾几年前的前端领域:JQuery  时代,虽然要手动操作 DOM,但其实在那时, Google Closure 和 Ext.js 团队就已经提供了完整的组件化概念,甚至  Ext.js 还提供了组件冒泡这样的创新事件机制。那时用 Zepto 维护的代码,编码速度甚至比现在写一些 React  项目还要快。不同的技术只是工具,怎么用工具,能把工具用到什么程度,最终取决于开发者自身,所以高质量的工程代码,更多应该从业务和工程的角度考虑问题,而非技术选型。

举个例子,当整个公司都在使用  React 开发时,虽然我们知道 Vue 使用可能会更简单便捷,但我们一定不会去用,因为这个时候,虽然看起来写代码更简单了,但其他人在  React 方向沉淀的经验,你无法复用,额外还需要整个团队去学习一套全新的技术,这样的工程设计,在这个背景下,显然是不合理的。

Thenewstack 做过 2019 年的开发者数据统计,开发者 32% 的时间用于业务开发,19% 的时间在维护代码,也就是工程师真正能投入到研发中的时间也只有工作时间的一半。对于开发者来说,这个时候通过合理的代码设计,提升代码的可扩展性,可维护性,降低开发和维护代码的时间,才是最强的诉求。

所以,高质量的工程代码应该是结合业务与团队情况,真正能够提升研发效率降低项目维护成本的代码。

谁决定了工程代码的质量?

木桶理论:木桶中能装多少水,不取决于最高的木板,而取决于最低的那块木板。同理,前端工程的质量,不取决于团队的平均能力,而取决于团队经验较少的技术同学的能力。在工作压力比较大的情况下,这些同学由于经验不足,短期又要完成需求,所以很多时候,并没有考虑过工程上的问题,而是直接面向实现功能编程,基本上我们现在面对的难以维护的代码,都是在这种条件下产生的。

木桶原理-木桶能装多少水取决于最短的那块木板

我们当然可以寄希望于经验较少的同学通过不断的成长来提升项目的工程质量,但实践下来,这并不可行。原因在于,工程能力的积累需要大量的编码经验,缺少实践经验的问题并不是短期就能够迅速解决的,任何好的工程师都是在不断犯错学习的过程中成长起来的。同时,工程开发过程中很可能会遭遇人员变动,一个团队的成员不肯能永远全部都是能力很强的。

那么我们就需要换一个策略来保障我们的代码质量,我们可以换个角度思考:是否可以通过一些规则,流程,编码上的约束,让编码能力不同的工程师,尽量写出质量相对较高的一致性代码。

通过约束提升工程质量

合理的约束让事情变得更简单

工作没有约束,工作中我们就难以形成共识,也无法判断工作做的好与坏。写代码也是一样的,没有约束,那么我们也无法判断代码是否合理。在流行的库和框架中,其实到处都是约束的影子,这里拿 Redux 和 React 的设计来举例:

通过约束(评审)提升工程质量

Redux 给出了单一数据源,State 只读,使用纯函数来执行修改这三个基本原则,同时要求通过 Action 的方式触发Reducer 的执行,这是 Redux 的约束;React 也给出了单向数据流这样的约束概念。

框架之所以是能够复用,能够得到推广,就是因为它们进行了封装,仅仅提供有限的约束能力供大家使用,这样大家才能形成一致的理念,编写互相能够读得懂的代码。理解了这一点,我们再来看业务工程的代码,实际上要提高开发效率和扩展性,无非也是要提供合理的约束。

工程代码的约束,更多带有一定的工程属性,如:

  • 规定相同的请求地址只允许在 API 层出现一次(项目接口数目多,可减少代码冗余)
  • 不使用超过 100 行以上的 Hook 代码(强化逻辑拆分,避免过度复杂的逻辑)
  • 在复用性和可维护性上做选择时,优先选择可维护性(避免错误封装,封装代码中耦合大量逻辑判断)
  • 业务代码注释覆盖率必须超过 10%(提升代码可读性,方便自动化生成文档)
  • 项目中跨组件通信必须通过 Redux (降低组件传值代码的团队理解成本)
  • 相同功能的 npm 包不允许安装多个(避免无用依赖安装,造成维护成本增加)

这些业务的约束,并不等同于 Eslint,不同的业务对代码的要求有可能千差万别,所以业务上的约束,需要研发人员充分的沟通交流,碰撞探讨,以及坚决执行。不同团队的同学,可能讨论出的结果完全不同,但约束的结论是什么本身不重要,重要的是形成一致的开发共识

通过机制实现约束的落地

约束本身并不难制定,对于工程侧的设计,工程师通过讨论比较容易形成博奕后的结论。但机制的落地是相对困难的一环。这里分享几个可执行的保障机制:

  • CodeReview(每次CR,除了对业务进行逻辑分析,也需要将是否遵循约束作为审核的一环)
  • 通过工具自动生成部分代码(比如使用脚手架生成工程代码中的某个模块,类似 AngularCLI 中 ng g component header 这样的指令,就可以帮你约束组件创建的代码结构)
  • 配置化生成代码(通过配置,生成逻辑或者表单代码,建立配置项标准)
  • 零代码 / PaaS 平台(通过平台生成代码,直接将用户与编码隔离,由平台保障生成代码的质量)
  • 负责人机制(约束落地直接与绩效相关联,成为跟进明确指标)
  • 沉淀文档(通过文档,沉淀约束机制)

通过这样的一些机制,保障约束有效的落地,那么我们就可以抹平团队成员技术能力的差异,形成一致性的编码风格。虽然这种约束下的代码并不一定是最优雅的代码,但至少工程质量不会差。所以这里我认为,约束实际上帮助我们保障的是工程质量的下限,那么接着我们来谈如何通过技术创新,提升工程质量的上限。

在约束之上寻求创新

大家可能会有这样的问题:“项目的约束,会不会限制技术的创新”。针对短生命周期的小型项目,这可能是对的,这种项目,使用更多的新技术进行探索突破可能会带来更多的团队技术储备;但对于大型项目来说,我们每天所做的代码设计决策,都可能会影响到明天业务系统的发展进程,任何技术升级都一定要慎重,这时候,我们不应该把约束当作创新的阻碍,而应该把约束当作创新的练兵场。

如果你在大型项目中,想突破约束,使用新技术,进行技术革新,那么一定意味着你要做到以下几件事情:

  1. 对过去约束限制的背景有充分了解:背景没有改变,新技术是否能解决约束所解决的问题,同时不会带来新的问题
  2. 能够充分表述新技术所能够带来的价值:在形成共识的问题上,新技术是否能对性能,稳定性,体验,研发效率,业务提效有明显作用
  3. 能够给出技术升级的整体方案:在确认要进行技术升级时,你是否考虑到历史技术方案如何优雅的实现替换
  4. 能够说服团队认可新的技术升级方案:在当前已有技术的基础上,你是否能说服团队成员和你一同推进技术创新
  5. 能够带领团队或者自己将技术方案落地:你是否具备能力将新技术或者创新点完成落地

很多时候,我们做的技术创新,其实只是技术栈的更新,并没有为团队和业务侧带来任何的价值,但当我们想清楚这些问题,能够有信服力的证明新技术或者创新点是有价值的时候,关于系统的升级可能才是真正有价值的。

在约束上的创新,可以让工程师结合业务有更多的思考,产出真正有价值的创新。而这些有质量的思考和创新,决定了工程质量的上限,同时也会培养出更多优秀的工程师。

如何提升已有工程质量?

对于一个全新的大型项目,我们可以通过上述的方式,分阶段进行架构设计和优化。但是,大多数情况下,我们接手的项目,可能在接手时就会发现其工程质量较低,那么我们应该如何对已有代码进行改良呢?

判断你的系统是否需要改良

一个系统的生命周期,可以总结为三个阶段:

  • 发展期:业务发展迅速
  • 稳定期:业务情况稳定
  • 衰退期:业务逐渐关停并转

对于发展期的系统和稳定期的系统来说,合理的工程设计未来能带来的性能,稳定性等方面的收益十分明显,这个时候,我们可以考虑对系统进行技术升级。而对于衰退期的系统,虽然短期开发维护效率不高,但无法看到未来系统的发展潜力,这时候,继续维护老系统可能是一个更好的选择。并不是每一个系统都必须要改良,精益求精固然好,但是否要做还是要回归到对业务价值的判断上。

如何进行工程改进

大型项目的工程改良,可以分为两种方式,自上而下,和自下而上。对于大型项目来说,自上而下的全部重构,成本很大,除非你对系统特别了解,否则并不推荐采用这种方法。相反,目前的主流框架,React, Vue 都是可以对局部 DOM 进行托管的,所以自下而上的逐步升级可能是更好的策略,这种方法有两个优势:成本低,风险小。举个自己工程中的例子,我们需要把 JQuery 升级至 React,采用了这种方式,逐层向上的对 JQuery 中的 Backbone 代码进行替换:

export default View.extend({
  componentName: 'AuctionDetailContainer',
  initialize(options) {
    const { dataSchemaV1, pageSchema } = options;
    this.ref = React.createRef();
    this.dataSchemaV1 = dataSchemaV1;
    this.children = pageSchema.getChildren()[0];
    this.attributes = pageSchema.getAttributes() || {};
  },
  render() {
    ReactDOM.render((
      <AuctionDetailContainerWithRef
        ref={this.ref}
        taskFields={this.dataSchemaV1}
        attributes={this.attributes}
        crossTableData={this.children}
      />
    ), this.$el[0]);
    return this;
  },
});

每一次替换,我们只要测试替换部分的逻辑即可,不会影响外部的其他逻辑,这样逐层替换,在保障稳定性和系统升级的双向要求下,做到了很好的平衡。同时,在接手新项目的时候,这种升级的方法还可以逐步帮你梳理清楚业务的逻辑,了解业务。

在这样的逐步替换过程中,结合之前说到的编码约束,我们就可以将系统的代码质量逐步完成提升。而之后,则可以通过创新的方式,进一步对项目优化完善,从而完成整个重构过程。

在这个过程中,有一些工具也可以帮助到我们,举几个例子:

  • CommintLint + SemVer 语义化版本号控制规范:帮助团队明确重构可能带来的风险,节约沟通成本
  • 前端自动化测试工具:通过单元测试保障工程质量,降低回归错误产生概率
  • Chrome Coverage:代码执行情况分析工具,帮助你找到无用代码,梳理项目逻辑

结语

本文跳出技术角度和思维,除了从代码本身的视角来提高整体工程质量,更从管理的角度,团队运作的角度,以效率和效益来阐述前端大型项目整体工程质量的把控和提升,希望对大家有所助益。

【干货长文】腾讯 IMWeb 前端部门解读2020 年大前端技术趋势及2021最新技术展望

在2020年尾,腾讯知名前端技术团队IMWeb给予实际业务和行业发展状况,对前端发展过去一年的趋势进行了分析、总结和梳理,并对2021年前端发展和最新技术趋势进行了展望,专业的团队成员和前言的实战,相信这份详细的技术趋势分析会对您有所启发。

IMWeb 前端团队早已不再拘泥于满足页面展示,而是开始延展到通过全栈来闭环产品。这表明前端已经有能力透过业务深入产业,继而影响商业结果。这种表象的改变背后是本质的转变,从更为宏观的角度来说,前端正在通过持续的技术革新和技术融合不断突破自身边界,进而重新定义自身价值。

时光荏苒,非比寻常的一年即将过去。在这过去的一年中,与其说前端的平稳期即将到来,不如说前端反而进入了技术深水区。换言之,在全栈和多端的影响下,前端领域里“术业有专攻”的时代已经到来。如今的前端早已不再拘泥于满足页面展示,而是开始延展到通过全栈来闭环产品。这表明前端已经有能力透过业务深入产业,继而影响商业结果。这种表象的改变背后是本质的转变,从更为宏观的角度来说,前端正在通过持续的技术革新和技术融合不断突破自身边界,进而重新定义自身价值。在这种大变革的时代背景下,腾讯 IMWeb 前端团队也正在与时俱进得进行着技术更新、优化与升级,结合自身这一年的快速发展,IMWeb 团队为大家带来 2020 年大前端技术趋势解读。

回顾2020的前端技术趋势

本文拟通过回顾 2020 年七大主要的前端技术趋势来展现前端早已由单纯工具解决问题的属性逐步转变为深入产品机制解决商业问题的角色。前端开发者的关注点也早已不是如何使资源利用效率更高,页面体验更优以及保证业务的稳定输出,而是更为关注产品能力、产业模式、数据建设以及商业转化。

开源站点 bestofjs.org 收录了 Github 上 1500 个开源项目,并且还基于 GithubTrending API 的公开数据,更新统计这些项目的 Stars 新增趋势。基于 Bestofjs 去年的 2019 年 JavaScript 明星项目(https://risingstars.js.org/2019/zh)报告和近一年 Trending 排行数据,下面展示了 Top30 的前端重点项目,并对此进行简单的介绍。

Github 上 1500 个开源项目Top30前端重点项目

相比于去年,学习资源越来越丰富了,Top100 内有 14 个项目是与前端基础学习相关的,侧面可以看出前端行业的繁荣;同时也反映出知识和人才的迭代速度是非常快的。Deno 超过 Vue.js 一跃成为过去一年 Star 增长最快的开源项目,打破了 Vue.js 连续 4 年登顶的垄断。虽然在工业届使用 Deno 落地在业务场景的情况还比较少,但是目前的发展势头还是不错的。还记得因为 Deno 的出现,出现的那句经典的“求不要更新了,老子学不动了”。事实证明“学不动的时代” 并没有到来。除了跟学习相关的项目,倘若只关注垂直领域的技术项目,我们会惊喜地发现:

  • TypeScript 持续升温,依旧保持着高速成长的状态,未来的潜力不可限量;
  • 通过项目分布的情况,明显能看到 React 生态圈>> Vue 生态圈>> Angular 生态圈;
  • 伴随着 WebAssembly 核心规范成为浏览器的标准,继 HTML、CSS 和 JS 之后,像 C/C++、Rust、Go 等语言编写的高性能模块也在浏览器上运行。相信在不久的将来,Web 应用的桌面客户端化,也将成为一种趋势;
  • Strapi 位列 Nodejs 相关领域的第三名侧面反应了低代码的趋势还在持续升温,各家都在研制自己的低代码平台来提升开发效率;
  • JS Framework 相关的领域,Next.js 超越 Nest 成为了今年的冠军。在强大的 React 体系的影响下,业务越来越多的人选择使用同构和直出的方案来构建 Web 应用;
  • Serverless Framework 也进入了前 Top100,虽然排名不高,但是已经开始慢慢展示出了可持续发展的势头。对于一个被厂商裹挟的技术而言,这一切来之不易;
  • 大前端生态系统已经逐步完善,前端工程化逐步完善,DevOps 已经走向了系统化的发展方向,前端技术已经进入深水区;
  • 由于直播行业的火热,以及疫情的影响,音视频领域在过去的一年也有着蓬勃的发展。在前端领域 WebRTC 的技术在持续升温。

接下来,主要盘点下在即将过去的 2020 年前端行业发生了哪些重要的事情,同时分享下腾讯 IMWeb 团队在过去一年中都做了哪些工作。

总结 2020 年度趋势

1、TypeScript 爆发增长

从 2019 年开始,社区内掀起了学习使用 TypeScript 的浪潮,从 npm 的下载量来看,近几年 TypeScript 呈现爆发式增长,甚至在 2020 年在 Github 语言的排行榜上跃居到了第四位。

数据来源:https://octoverse.github.com

相比于同类型工具,如 Elm、ClosureScript、CoffeeScript 等,TypeScript 可谓是一马当先:

TypeScript最新排名领先第一
数据来源:stateofjs2019

在最新的 2020Stack Overflow Survey 中,TS 受大家喜爱程度排名第二,仅次于 Rust:

最新的 2020Stack Overflow Survey 中,TS 受大家喜爱程度排名第二,仅次于 Rust
数据来源:StackOverflow Survey Result 2020

在如此爆炸式的增长浪潮中,TypeScript 必将给前端生态带来新的气象,同时也会促使前端开发者更多地关注代码设计、易用可维护、编码原则及设计理念等方面的知识。

IMWeb 团队自 2018 年起开启第一个 TypeScript 项目,至今已完成绝大部分业务向 TS 的转型迁移。在多端复用模块代码中,以 TS+ Jest 为基本要求,保证公共代码的可维护性和可测试性:在 TS 编写中,我们更多地遵循面向对象设计原则(SOLID 原则、KISS 原则等),适当的运用设计模式,帮助更好地进行代码开发和维护。同时,在 TS 践行中,辅以单元测试覆盖,可以指导我们更好地拆分组织代码,编写可测试的模块,在公共核心业务模块中覆盖单测用例。

2、三大框架 React 当先

前端界的三大主流框架:React、Angular 和 Vue.js,今年仍是炙手可热。此外,在过去一年,这三大主流框架还迭代了许多版本。在三大框架之中,根据过去一年的 NPM 下载量,React 仍然稳居首位。

前端界的三大主流框架:React、Angular 和 Vue.js,今年仍是炙手可热。此外,在过去一年,这三大主流框架还迭代了许多版本。在三大框架之中,根据过去一年的 NPM 下载量,React 仍然稳居首位。
React 仍然稳居首位

2020 年的 StackOverflow Trends 显示 React> Vue.js > Angular;

React> Vue.js > Angular

在 Github2020 年的新增 Stars 数量上,Vue.js 依旧超过了 React。

Github2020 年的新增 Stars 数量上,Vue.js 依旧超过了 React
Github2020 年的新增 Stars 数量

下面分别总结各个框架 2020 年的动态:

1、React

React 自发布 v16 版本后,迭代的版本都是以修复、优化为主,当前最新版本 v17.0.1,今年 8 月正式推出的 v17 版本,并无显著的新特性,而是一个”垫脚石“版本。为了后续能兼容 v18 版本,或者说是为了能达到”逐步“升级的目的,这也能规避当项目的依赖存在多个版本 React 时出现问题。这种逐步升级的理念与 VUE 的渐进式兼容升级颇为相似。

2、Vue.js

2020 年 Vue.js 的重大变化无疑是 Vue.js3.0 的发布,有了非常多新特性,总结如下:

对 Vue.js 进行了完全 Typescript 重构,让 Vue.js 源码易于阅读、开发和维护;

重写了虚拟 Dom 的实现,对编译模板进行优化、组件初始化更高效, 性能上有较大的提升;Vue.js2 对象式组件存在一些问题:难以复用逻辑代码、难以拆分超大型组件、代码无法被压缩和优化、数据类型难以推倒等问题;而 CompositionAPI 则是基于函数理念,去解决上述问题,使用函数可以将统一逻辑的组件代码收拢一起达到复用,也更有利于构建时的 tree-shaking 检测,这个使用起来有些类似于 React 的 hook;

以上变化都秉持着 VUE 的“渐进式框架“ 理念, Vue.js3.0 持续开发兼容旧的版本,即使升级了 Vue.js3.0 也可以按照之前的组件开发模式进行开发。

3、Angular

Angular 在今年 11 月推出了 v11.0.0 版本,主要变化为:

将其依赖的 Typescript 版本升级至 4.0, 不再支持 Typescript3.9 版本;

Angularv11 在继 v10 弃用 IE9、10 和 IEmobile 支持后,将其完全删除;

加入了 Webpack5,升级至 Angularv11 版本,即可使用 Webpack5 的新特性,如更快的构建速度、模块联邦等。

IMWeb 团队的前端技术栈主要围绕着 React 体系进行构建的,包含了基于 Webpack 的最佳实践 IMFLOW,以及围绕着 React 体系完成的组件生态。在三大框架逐渐同质化的今天,未来的你使用何种框架就得由工作岗位的需求来决定了。

3、WASM 展露头角

WebAssembly 源于 Mozilla 发起的 Asm.js 项目,也被称为“设计补充 JavaScript”,其本解码速度比 JS 解析快得多,让高性能的 Web 应用在浏览器上运行成为可能。该模块可在浏览器中的专有虚拟机上执行,与 JavaScript 虚拟机共享内存和线程等资源。目前主流浏览器基本都支持了 WebAssembly。

主流浏览器基本都支持了 WebAssembly
主流浏览器基本都支持 WebAssembly

在 2019 年 12 月 15 日 WebAssembly 正式成为 WorldWide Web Consortium (W3C) 的标准,加入到了 HTML、CSS 和 JavaScript 的行列,继而成为浏览器官方的标准的第四门语言。WebAssembly 也正式抵达了 1.0 版本,获得了主流浏览器 Firefox、Chrome、Safari 和 Edge 的支持。

首届 WebAssemblySubmmit 2020 年在硅谷举行 (https://Webassembly-summit.org/),会议上讨论了诸如:关于构建 WebAssembly 新型生态系统;WebAssembly 的未来以及 WebAssembly 与诸如 Javascript 等其他支持技术的关系;WebKit 的 WebAssembly 实现的编译、启动和运行时等 benchmarking 领域进行的研究和开发;其中 Ben 演讲的“Expandingthe PIE” ;

WebKit 的 WebAssembly 实现的编译、启动和运行时等 benchmarking 领域进行的研究和开发;其中 Ben 演讲的“Expandingthe PIE”
Expandingthe PIE

短短几年的时间里,WebAssembly 取得了长足的进展。

Ability

目前有 100 多个不同的项目使用 WebAssembly。这些应用包括:自由手绘应用程序、媒体播放器、Gameboy 仿真器、浏览器内压缩 / 解压应用程序,甚至还有一个 AR 数独解谜应用程序。

Producer

目前大约有 15 种编程语言可以以稳定的、面向生产的方式编译到 WebAssembly。其中包括:.Net,AssemblyScript,C,Haskell,Rust 和 Zig 等,还有更多的正在开发中。

Interoperability

WebAssembly 现在有了一个基于能力的 API 设计,它允许 WebAssembly 代码与外部世界交互,同时仍然保留了 WebAssembly 的沙盒特性。此外,曾经强大而有用的 WebAPI 集合现在正在不断得到实现。

Embedder

现在可以在许多不同的平台上运行 WebAssembly。目前正在积极开发的运行时大约有 20 个。WebAssembly 不再局限于浏览器。这里有区块链实现、无服务器应用程序、操作系统可执行程序和物联网实现的例子,它们被部署在独立和受限制的嵌入式运行时环境中。

看到这么多不同的项目和运行时,真是令人惊讶!而 2021 年的 WebAssemblySubmmit 会在 4 月举行。随着 WebAssembly 的不断发展,Web 中文兴趣组·WebAssembly 研讨会也在今年的 8 月 29 日在线上举行,重点探讨了 WebAssembly 技术应用与实现,尤其是在多媒体、编译器以及新型语言、仿真器、Web 前端框架、虚拟机、云、游戏引擎、工具等多方面的应用场景。在未来的一年里,WebAssembly 会有更多的机会出现在大家的面前,我们也会在业务中落地基于 WebAssembly 的应用。

WebAssembly 的出现为 Web 开发者打开了一扇新的大门。在去年,wasm 对你来说也许还仅是技术文章中的一个常见名词,你压根想不到他会在浏览器中得到怎样的应用,什么时候会被大公司真正用起来。在今年,你很有可能已在不知不觉中成为 wasm 的使用者了。目前国内外越来越多的团队基于 wasm 进行了业务实践。

IMWeb 团队擅长的音视频领域,我们通过将 ffmpeg 编译为 wasm 版本且在浏览器中运行,将过去处于黑盒中,只有浏览器底层才能使用的音视频编解码能力彻底解放。目前我们可以在前端页面中对音视频流直接进行处理,在完全不依赖后台的情况下,便捷、高效的实现了视频播放帧预览与视频帧截图等功能。目前团队正在进一步探索 wasm 在音视频以及其他过去前端无法触及的领域的可行性实践。

4、Low-Code 恰逢其时

·从 2014 年 Forrester 的研究报告提出“low-code”一词到今天,低代码领域持续升温。从低代码领域的行业角度看,2017 年后,微软、甲骨文等各大厂家纷纷加入了低代码赛道的竞争。近年来,获得 3.6 亿美元融资的 Outsystems 更是成为低代码领域海外市场的一只独角兽。国内方面,也不乏云凤蝶、点石、iVX、轻流、积木等平台的诞生,低代码产品领域的蓬勃发展,正成为特定场景软件开发的重要趋势。

区分一下 no-code、low-code、pro-code

no-code: 自己编程给自己用,给用户的感觉就是一个软件。因此,平台不会给自己定位成一个“编程工具”。主要是通过图形化的操作来降低学习曲线,类似 PPT、Excel 等。在垂直领域的特定场景中,才能做到好用。

low-code: 编程给其他人用,通过降低专业难度,让运营人员(CitizenDeveloper)也参与进来。平台评估好预制的场景和需求,减少从头写代码的成本,一定程度上可以通过图形化的方式满足业务诉求。

pro-code: 日常软件开发过程中的手写代码,可以通过逻辑和模块复用来进行提效。

区分了概念之后,还需要考虑面向的用户。不同的用户对应着不同的解决方案。用户大致分为三类:前端开发人员、后台开发人员、产品运营人员。

为什么要做低代码?

基于目前可视化和模型驱动理念,结合当下大前端跨端体验的融合技术以及云原生的支持,通过低代码的方案可以大幅度降低业务交付的成本,为业务提供一种全新的开发范式。而且,可视化搭建去完成业务可以让产品和运营人员(CitizenDeveloper)参与进来,可以极大得释放软件开发者的人力瓶颈,也进一步促进了技术和业务的深度合作。

低代码应该具备哪些核心能力?

基础物料的搭建和接入是保证业务可视化的基础。 无论是行业的开源组件,还是团队自定义的基础组件,搭建平台都应该无缝地进行预期内的接入和控制。这是因为,从业务长期迭代的角度来看,最耗费人力的一定是最频繁的业务组件。解决定制化的组件和接入组件由此成为低代码平台长期需要解决的最核心问题。

编排能力就是页面排版和对逻辑编排。 无论是特定场景的页面的组件逻辑,还是用户自定义的交互(包括用户行为的服务端能力支持)都应该通过逻辑编排能力进行支持。大部分的页面搭建工作都是在桌面端完成的,但是页面渲染的产物可能是多种形式的,比如:PCWeb、H5Web、小程序,那么在搭建运行时的实时可视化和搭建完成的多端适配和多场景适配,这样就解决了跨技术栈和跨端问题;

虽然是 low-code 的设计方案,但还是希望输出的代码是可以进行二次开发的,因此最好能 pro-code 与 low-code 互相转换。编程产物分为初级产物、中间产物和最终产物。产物的丰富程度,直接决定了平台的可复用性和灵活性。无论是基于低代码开发和源码的混合开发,还是基于低代码平台的二次开发,都是 low-code 平台需要考虑的事情。

运行时能力也非常重要, 对开发者来说是一个强大的编辑器引擎,可以方便快速接入各类组件和中间件。而对于运营人员(CitizenDeveloper)来说同样也很重要,针对不同的产品和业务场景,需要定制基础业务模版和和业务配置,方便他们快速地进行差异化的功能设计。

协作能力和数据分析能力就不言自明了。低代码平台的核心就是降低对专业性的要求。 因此,使用者无论是谁,都应该有更高的效率提升。而数据统计和分析是所有平台都应该具备的基础能力,这里就不详细描述了。

那么,整理了核心能力如下:基础资料的搭建、基础资料的接入、业务编排能力、界面渲染能力、代码转换能力以及运行时能力、协作能力和数据分析能力。以上就是我认为的低代码方案应该具备的能力模型。

为什么说 low-code 是恰逢其时呢?因为无论是跨端和跨平台领域的强大适配能力,还是大前端工程体系的有力支撑,都已经将低代码领域的价值逐步推到人们面前,低代码是业务发展和技术探索的必然选择。

2020 年 IMWeb 团队在低代码领域不断优化升级面向运营场景的页面搭建平台 Vision,在真正意义上实现了对运营系统和素材开发的解耦,并兼容 React,Vue.js, JQuery 等不同技术栈,实现了 PC、H5、微信小程序的可视化运营的页面搭建。

Vision-2020 年 IMWeb 团队在低代码领域不断优化升级面向运营场景的页面搭建平台 Vision
页面搭建平台 Vision

与此同时,在 Vision 系统的基础上,我们沉淀出一套可视化搭建引擎 Gems,针对日渐增加的 B 侧需求,以 Gems 为核心开发了专注于搭建管理系统的平台 Hulk,实现了相对运营页面更为复杂的管理页面甚至数据接口的可视化搭建与生成。

Hulk-Gems 为核心开发的专注于搭建管理系统的平台 Hulk
Gems 为核心开发的专注于搭建管理系统的平台 Hulk

我们的目标是通过 Hulk 实现对 80% 日常业务页面的“0 代码”搭建。通过 Node.js 统一管理数据接口,可以通过图形化配置,快速创建接口,组合不同数据源的数据;支持多组件灵活配置生成页面的能力,扩展组件库,开发常用组件;复杂页面和接口逻辑支持低代码扩展。

Low-Code 领域的发展在 2020 年极其迅猛。从最早的通过模块化搭建解决营销活动领域的问题发展到现在可以通过 low-code 来解决内部复杂的中后台业务需求,既适用于面向 C 侧用户的产品运营,也贴合 B 侧用户的数据管理需求。

5、全栈开发持续深耕

从 DevOps 到 NoOps 的路径之一,便是目前大家都在尝试的 Serverless 了。 自从 2012 年有了 Serverless 的概念开始,至今已经 8 个年头了。近年来随着国内的云厂商,如腾讯云、阿里云、华为云对 Serverless 的支持,并且伴随着小程序云开发的普及,国内的开发者对 Serverless 的使用已经非常熟悉了。

今年 9 月 CodingSans 联合其 9 个合作伙伴,发布了 Serverless2020 年度状态报告。调查结果显示:有 75% 的开发者会在公司使用这项技术。如此高的 Yes 也基本反映出了这样的技术已经被大众普遍接受并使用。

Serverless2020 年度状态报告
Serverless2020 年度状态报告

我们可以看到开发者选择应用 Serverless 的场景有很多,比如:为小程序、Web、Mobile 提供基础性的 API 服务,大规模批处理任务处理,Web 站点、DevOps 的工具以及 GraphQLAPI 能力。

Serverless 的场景有很多,比如:为小程序、Web、Mobile 提供基础性的 API 服务,大规模批处理任务处理,Web 站点、DevOps 的工具以及 GraphQLAPI 能力
Serverless 的试用场景排名

目前最大的难题是调试,这主要是由 Serverless 的架构复杂性所引起的。 而供应商之间的巨大差异也使得更换或者说迁移供应商变得非常得不偿失。

与其说 Serverless 是一项技术,不如说 Serverless 是一种理想的工作模式,是一种专注于业务价值的思考。 单纯的通过函数进行业务交付,而不再需要关心解决业务问题之外的事情,比如:那些非常繁琐的基础设施。托管服务可以让开发者更专注于编写业务函数,从而减少对机器资源、降低运维成本的考虑,可以让开发者更专注的为产品和用户创造价值。随着云厂商对于 Serverless 的支持,后续会有越来越多的开发者,可以体会到云时代给大家带来的便利。

IMWeb 团队开始 Serverless 的实践也非常早。随着腾讯云的发展,在 2019 年就已经将 SCF 落地在业务中了。而 2020 年为了提升 SCF 的开发体验,又完成了开发体验的全面升级,可以在 10 分钟内完成一个云函数的上线。

IMWeb 团队开始 Serverless 的实践
IMWeb 团队开始 Serverless 的实践

IMWeb 团队更宏大的全栈开发计划也在 2020 年稳步进行中。跟随着公司上云的战略,2020 年团队依托于云提供的基础能力进行了一系列的全栈架构演进。与时俱进的制定了新的研发基础规范、持续性的丰富业务基础组件、打造更佳完善监控和告警体系,并结合公司内优秀的开源项目协同共建,持续深耕全栈开发。目前已经在业务中落地了多个由前端主导的业务解决方案。这不仅减少了后台人力的投入,也极大得拓展了前端的边界,提升了前端在业务中的价值。

6、DevOps 渐进增强

研发效能是 2020 年提到的比较多的一个热词,特别是在腾讯内部,提到效能不得不提到近几年非常火热的 DevOps,开发运维一体化流程,CI/CD 流程的串联,帮助业务提升研发效能。

研发效能,DevOps,开发运维一体化流程,CI/CD 流程的串联
研发效能 DevOps
DevOpsSurvey
DevOpsSurvey

在 2020 的 DevOpsSurvey 中,DevOps 带来的正面影响获得了 99% 的认可度:

DevOps 带来的正面影响获得了 99%
DevOps 带来的正面影响获得了 99%

不过,想要完全达到 DevOps 的效果,难度是很大的,DevOps 链路涉及到非常多的工具链,使用学习成本较高,在当前服务稳定的情况下,迁移 DevOps 技术栈将遇到不小的挑战。

IMWeb 在 DevOps 实践是基于业务上云,在云原生的基础上完成的。其中包括:

  • Node 服务上容器平台 STKE(基于 K8s 定制)
  • CDN 对接腾讯云 COS 平台
  • BFF 层、小程序等使用 Serverless 服务
  • CI 规范化构建、检查、测试流程
  • IMWeb 自研 Thanos 平台串联 DevOps 一体化流程

对于 DevOps 各流程的把控和规范,IMWeb 团队自研 Thanos 研发效能平台,帮助在线教育部所有前后端团队业务完成 DevOps 转型:

7、WebRTC 持续升温

随着互联网的不断加速和音视频技术的不断发展,许多以音视频技术为依托的产品相继面世,比如:直播、短视频等等。从 3G 到 4G,再到即将到来的 5G 时代,移动网络的带宽和质量越来越高,海量低延迟直播、互动直播也成为了可能。音频技术发展到今天,实际已经非常成熟了。从 H264/H265、VP8/VP9 以及后面的 AV1 编解码器,解决了视频压缩率的问题;而 5G 的商用,解决了带宽的问题。这两个问题解决后,各行各业都开始使用音视频技术来实现更佳的用户体验,比如:音视频会议、直播带货、在线教育、远程医疗、娱乐游戏等等。2020 年由于疫情的影响,大家更多地认识和了解到音视频相关的行业。音视频技术底层离不开编解码标准的发展。而就在今年,新一代国际视频编解码标准(H.266/VVC)正式出炉,其后续的落地实践非常值得关注。从行业应用的发展来看,围绕音视频直播一定会有三个发展方向:更快、更便宜、更智能。之前音视频领域有两大技术路线:一类是 RTC,它主要用于满足多人会议中的低延时互动;另一类是流媒体直播 / 点播,主要满足于对延时要求不大的高并发低成本场景。而端上的音视频处理技术主要围绕更智能,诸如人脸识别、美颜、降噪、超分等处理优化来展开, 行业中也有更多的实践落地,从后端到前端都在探索更为极致的体验。

WebRTC 有个特别宏伟的愿景:可以在浏览器上快速开发出各种音视频应用。但这早已不再仅仅是愿景,而是已经在逐步成为现实。

WebRTC 持续升温

从 Chrome、Firefox 到近几年苹果 Safari 的加入与支持,各个云服务厂商、腾讯云、阿里云、网易云、七牛云以及诸如专门音视频服务商(声网和即构科技等等),都将 WebRTC 纳入浏览器实时音视频首选方案。

从 StackOverflow Trends 和 GoogleTrends 来看:WebRTC 的热度不断上升,而且由于 2020 年初疫情的影响,直播带货、在线会议和在线教育等远程实时音视频技术的也迎来了风口,关注度急剧上升。下面是我们总结的 WebRTC 应用层面的知识图谱:

WebRTC 应用层面的知识图谱思维导图
WebRTC 应用层面的知识图谱思维导图

早在 2016 年 IMWeb 团队就率先对 WebRTC 进行探索和实践。我们是腾讯公司内最早将 WebRTC 落地于业务的团队之一,也是腾讯云 WebRTC 直播能力最主要的使用者。2020 年初,由于疫情,在线教育迎来爆发式的增长。为了保障受疫情影响而无法返校的学生能够继续通过线上课程完成学业,我们开展了“停课不停学”活动。在此期间对原有的 WebRTC 互动直播 +CDN 云直播能力进行了全面升级,集成了快直播能力与语音举手功能,使更多的用户可以享受 WebRTC 带来的低延迟、高性能的互动直播体验。

疫情渐渐平缓,IMWeb 音视频小分队的脚步没有因此而停缓。2020 下半年,我们又做为公司内勇于第一个吃螃蟹的人,相继上线了腾讯课堂的 Web 视频连麦能力,推出了团队自研的 WebRTCSDK 与之相配套使用的 LokiPlayer 播放器。LokiPlayer 集 WebRTC 互动直播、快直播、云直播、降级流控、点播等能力于一身,本身就已是集大成者,又通过提供基于插槽与注入实现的插件化能力保证播放器与 SDK 本身都可以被业务灵活的扩展。

团队自研的 WebRTCSDK 与之相配套使用的 LokiPlayer 播放器
IMWeb团队自研的 WebRTCSDK 与之相配套使用的 LokiPlayer 播放器

在 2021 年,我们将继续深入研究音视频的底层原理,探索更多在 Web 浏览器能得到应用的技术,持续性地优化诸如音视频体验、音视频质量以及测试与定位等能力。结合 wasm,将之前无法想象的功能逐个实践、逐个实现落地。明年将与终端播放器一起对外进行开源。如果你恰好是 Web 音视频技术的使用者,千万不要错过!

展望 2021 技术趋势

技术的核心价值是为业务创造价值。那么,如何能快速满足业务发展诉求呢?首先,我们始终离不开解决成本、效率、质量三者之间的平衡。因此,提升基础物料的可用性、提升开发工具的便捷性、完善动态运营的灵活性以及解决产品质量的稳定性,这些永远都会在我们的日常工作中持续进行,并且在追求极致的道路上永无止境!

正所谓分久必合,合久必分。无论是选择极权式的中台化解决方案,亦或是选择去中心化的业务自制模式,都可以提升技术在业务的影响力。当然选择什么样的方式,这与企业自身的基因和团队发展的阶段有很大的关系。

在垂直领域的技术发展方面,我们对 2021 年可以做一些展望:

  • 三大框架的同质化会越来越明显,而周边配套还在可持续的发展中。从开发者的基数上可以看到未来一年 React 还是会持续性地领先,但这并不妨碍 Vue 的优秀;
  • 由于可维护性和系统的复杂度上升,TS 未来一年依旧会保持强劲的势头吞噬 JS 的版图,未来会有更多的开源框架和基础组件拥抱 TS 社区。
  • 大前端领域的前端工程化如今已经慢慢成熟和稳定了,而在未来一段时间,更多是基于全栈开发的工程化体系的建设。前端开发者会更多的借鉴后台开发的经验去加速这一历史进程的速度,尽快完成全栈研发体系的升级和探索。
  • 随着 WebAssembly 持续性的发展,会有越来越多的产品在业务上落地 WASM 这项技术。而随着 WASM 的发展浏览器桌面应用化的趋势也会越来越明显。WebOS 未来是否能够落地,相信 WASM 在其中一定扮演了重要的角色。
  • 小程序的标准化虽然提上了日程,但是由于有微信这样超级 APP 的存在,标准化的道路注定不会平坦。跨端开发上最耀眼的明星还是 Flutter,而苹果公司发布的 SwiftUI 也在路上了。从开发者的角度来看,多端同构是一种美好的愿望,但是任重道远,仍然需要长期且持续性的攻坚克难;
  • 与其说是 Serverless 不断地持续升温,不如说是泛前端的时代已经到来。前端团队寻求价值的渴望驱使着开发者们不断突破着自己的工作范围;前端服务化的工作模式已经从萌芽阶段发展到路人皆知的阶段了,大前端服务化的趋势已经是这个时代不可逆转的趋势了。
  • 随着 5G 网络的普及和手机硬件的不断提升,流量瓶颈和渲染性能在未来一年会有质的提升,这其中最大的受益者就是从事音视频领域的开发者。相信在未来的一年里,音视频领域一定是百花齐放的状态。
  • 低代码的场景天然的靶场就是在 B 端业务中进行抽象和实现。而随着产业互联网的提出,整个行业进入了 ToB 的转型期,未来的低代码会越来越受到大厂的重视。当然,低代码还是要持续解决三大问题:基础平台的能力完善、开发质量更加可控,以及低代码产物的可维护性提升。可以遇见的未来低代码会火爆的表现,并且会在生产中绽放光彩。

以上内容由腾讯 IMWeb 团队集体创作,希望对大家对来年的学习有所帮助,如果有需要其他的学习资料和最新文章,欢迎评论留言。

2020十大人口净流入城市排行:南多北少,南方用电吃紧,是否侧面验证经济南移

随着年关将近,2020十大人口净流入城市名单出炉,从排行版上看,前十分别是对42个重点城市的人口净流入情况中人口净流入最多的前10个城市分别是:上海、深圳、北京、东莞、广州、天津、佛山、苏州、宁波和杭州。

按经济圈统计,其中粤港澳大湾区(珠三角)4个,长三角4个,京津冀2个,按南北地理来分,南方城市8个,北方城市2个,南方完胜北方。

而此前一度热议的中国经济前十的榜单中,南方9城几乎霸榜,北方城市仅剩北京一席进入前十,天津创纪录的跌落前十。

同时,最近南方省份浙江,江西和湖南频频爆出限电使用,南方部分地区用电吃紧的情况,国家发改委也做出回应,工业生产高速增长和低温寒流叠加导致电力需求超预期高速增长。目前为止电力供应保持平稳有序,居民生活用电未受影响。国家发改委已会同相关部门企业,采取措施切实保障电力需求,确保电力供应总体平稳有序。

以上接连几个热搜,似乎关联不大,但细细琢磨,其实经济情况依然分晓,用电情况,不管是居民居家用电还是工业生产用电,这都是以人存在为前提,只有人口较为密集的地方才有较大的可能出现这种情况,所以南方用电吃紧也从侧面进一步验证了经济的活跃性南方显然是大于北方。

作为2020年各大城市的重头戏,抢人大戏也到年末晒成绩的时候了。先有深圳真金白银给补贴开始抢人,后有杭州、西安,武汉、成都等城市陆续跟进,最后上海也下海抢人,放松了之前高高在上的落户门槛,名校以及特殊技能人才可直接申请上海户口,广州也升级抢人大战,宣布除了主城四个区,其他区的落户条件进一步降低,购房资格也进一步降低,28岁以下的中专毕业人口一年社保即可落户,目的很明显,抢的就是年轻人。

而这一些列的操作成效也很明显,在人口流入方面,这些城市表现不俗。

相关数据统计显示珠三角人口密度最高

珠三角的东莞和广州分列四、五位,两市的人口净流入都超过了570万人。目前,净流入人口超过500万的也就四个一线城市和东莞。

值得注意的是,在人口净流入前五名的城市中,有3个来自珠三角地区,分别是深圳、东莞和广州。此外,珠江西岸的佛山净流入人口也超过了350万人,位居全国第七,可见珠三角对外来人口的吸引力。

根据国家卫健委此前发布的《中国流动人口发展报告2018》,2016年珠三角城市群常住人口达到了5998.5万,常住人口密度为1033人/平方公里,是全国平均人口密度的7倍多,也是全国人口密度最高的地区。2016年,珠三角净流入人口为2647.97万人,占常住人口的44.14%。

广东省统计局发布的2019年广东人口发展状况分析指出,2019年,广东省常住人口数量继续居全国首位,占全国人口总量的8.23%,比上年提高0.1个百分点,人口密度为全国的4.40倍。“全面两孩”政策实施持续发挥作用,人口流动进一步大城市化和都市圈化,数量庞大的外来人口以及相对较高的自然增长率减缓了老龄化进程。

长三角也有4个城市净流入数量位居前十,分别是榜首的上海,以及分列八到十位的苏州、宁波和杭州。后三个城市的人口净流入规模要小一些,合计为737万人,还不及一个深圳的规模。

从净流入人口占常住人口的比重即净流入比来看,有9个城市超过了30%,分别是东莞、深圳、中山、佛山、上海、厦门、广州、北京和苏州,主要来自三大经济区以及闽南三角洲。其中,珠三角地区就占了五席,且前四名均来自珠三角。东莞和深圳两市的净流入比更是超过了50%,分别为70.34%和59.02%,外来人口明显超过了户籍人口,呈现出典型的倒挂现象。

对东莞、深圳等地来说,加快推进外来人口市民化是这些城市发展的一大要务。在这一过程中,除了降低落户门槛外,加快医疗、教育等公共服务补短板是重中之重。比如从每万人拥有卫生机构的床位数来看,东莞仅为37.1张,深圳这一数字也仅为38.1张,跟武汉、成都、重庆、杭州、郑州、长沙等城市相比均有非常大的差距。

彭澎认为,过去很长一段时间,一个城市医院的床位数、执业医师数量都是按照户籍人口的数量来定编的。尽管这几年沿海城市也逐渐在按常住人口来配备医疗资源,但总体来看,一些外来常住人口很多的城市,配备的医疗资源还是不够,仍需要加快补短板。

厦门大学经济学系副教授丁长发对第一财经记者分析,长三角和珠三角等发达地区都有大量的外来人口,当前这些地方常住人口城镇化率都已经很高了,接下来最重要的是要提高城镇化的质量。尤其是这些地方有相当多外来常住人口没有户籍,没有享受基本公共服务产品的供给。但教育、医疗、养老、住房等公共配套投入都是需要钱的,因此需要财权、事权对称。

人口是第一大资源,代表的是现在,更是未来。

月入25k的前端开发都会的VUE面试,题吐血总结,涨薪必备

前端入门容易难,薪资低,如果要涨薪水,还得有过硬的技术积累和充分的笔试面试准备才能过关斩将,废话不多说,直接上干货

基础篇

基础篇

1、css只在当前组件起作用

2、v-if 和 v-show 区别

3、$route和$router的区别

4、vue.js的两个核心是什么?

5、vue几种常用的指令

6、vue常用的修饰符?

7、v-on 可以绑定多个方法吗?

8、vue中 key 值的作用?

9、什么是vue的计算属性?

10、vue等单页面应用及其优缺点

11、怎么定义 vue-router 的动态路由? 怎么获取传过来的值

12、watch和computed差异

13、组件中data为什么是函数

扩展篇

14、对于MVVM的理解?

15、VUE生命周期的几个阶段

16、什么是vue生命周期?

17、vue生命周期的作用是什么?

18、第一次页面加载会触发哪几个钩子?

19、DOM 渲染在 哪个周期中就已经完成?

20、VUE实现数据双向绑定的原理

21、VUE组件间的参数传递

22、VUE的路由实现:hash模式和history模式

23、VUEX是什么?怎么使用?哪种功能场景使用它?

24、对keep-alive的理解

25、虚拟DOM的优缺点?

26、vue的watch的深度使用

27、vue与react的选择

28、vuex中mutation和action的详细区别

29、vue-router中导航守卫有哪些

30、简述vue中diff算法原理

有了基础还不够,本次针对Vue专门

Vue专题

1. 谈谈对Vue的认识

vue的语法很简单,很容易上手,可以说就是对着模板来填充内容.想要动态绑定的数据,那么就在data中填充内容.想要具体的method,那么就在methods属性中填充内容.想要显示变量就用双花括号.可以说是很简单了.

vue使用的是MVVM模式,并且使用简单的命令加数据来进行DOM操作,让我避开了进行繁杂的获取,创建和删除DOM元素的操作.

借助vue的vue-router插件,可以很方便的实现单页面应用的搭建.并且可以实现浏览器中的回退效果.

vue的组件化开发可以说很方便的就实现了组件的复用.之前想要写复用组件的时候,一方面要写重复的html,另一方面把对应的CSS文件和JS文件独立开来,需要的时候进行引入.但是vue把三者放在同一个文件中,可以说非常的贴心,修改也很方便.

2. Vue组件中,在生命周期的哪个阶段,可以开始访问操作DOM?

什么阶段才能调用DOM

在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。

什么阶段能发起请求

  • 可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。
  • 但是推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:
    • 能更快获取到服务端数据,减少页面loading 时间;
    • ssr不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

3.父组件与子组件在销毁过程中怎么执行生命周期钩子函数?

Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:

  • 加载渲染过程

父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

  • 子组件更新过程

父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

  • 父组件更新过程

父 beforeUpdate -> 父 updated

  • 子组件销毁过程

父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

  • 父组件销毁过程

父 beforeDestroy -> 父 destroyed

4.计算属性(computed)与观察钩子函数(watch)之间的区别

  1. 计算属性是依赖的值改变会重新执行函数,计算属性是取返回值作为最新结果,所以里面不能异步的返回结果。不能写异步逻辑。
  2. 侦听属性是侦听的值改变会重新执行函数,将一个值重新赋值作为最新结果,所以赋值的时候可以进行一些异步操作。

5.v-show与v-if有什么区别

两个都是让元素不可见。但是两个选项有区别

  1. v-if 在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销比v-show大
  2. v-show控制的时元素的display属性,无论初始条件是否成立,都会渲染标签。而v-if是惰性的,只有在条件成立时才渲染为真实的标签,条件为假,不会去渲染标签

6.Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。简单点说,方便父子组件及组件之间的数据传递。
有 5 种,分别是 state、getter、mutation、action、module

vuex 的 store 是什么?
vuex 就是一个仓库,仓库里放了很多对象。其中 state 就是数据源存放地,对应于一般 vue 对象里面的 datastate 里面存放的数据是响应式的,vue 组件从 store 读取数据,若是 store 中的数据发生改变,依赖这相数据的组件也会发生更新它通过 mapState 把全局的 state 和 getters 映射到当前组件的 computed 计算属性。

vuex 的 getter 是什么?
getter 可以对 state 进行计算操作,它就是 store 的计算属性虽然在组件内也可以做计算属性,但是 getters 可以在多给件之间复用如果一个状态只在一个组件内使用,是可以不用 getters。

vuex 的 mutation 是什么?
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。也就是说,前面两个都是状态值本身,mutations才是改变状态的执行者。
注意:mutations只能是同步地更改状态。

vuex 的 action 是什么?
action 类似于 muation, 不同在于:action 提交的是 mutation,而不是直接变更状态action 可以包含任意异步操作 vue 中 ajax 请求代码应该写在组件的 methods 中还是 vuex 的 action 中。

vuex 的 module 是什么?
面对复杂的应用程序,当管理的状态比较多时;我们需要将vuex的store对象分割成模块(modules)。

7.r o u t e r 和 router和router和route的区别

this.r o u t e r 是 V u e R o u t e r 的 实 例 方 法 , 当 导 航 到 不 同 u r l , 可 以 使 用 t h i s . router是VueRouter的实例方法,当导航到不同url,可以使用this.routerVueRouter的实例方法,当导航到不同url,可以使用this.router.push方法,这个方法则会向history里面添加一条记录,当点击浏览器回退按钮或者this.$router.back()就会回退之前的url。

r o u t e 是 route是route是router跳转到的当前一个对象,里面包含该对象的path、query、name 、params

this.$route相当于当前激活的路由对象,包含当前url解析得到的数据,可以从对象里获取一些数据,如name,path等。

8.Vue和React的区别

区别

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

  • Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
  • React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的VDOM的重新渲染

为什么 React 不精确监听数据变化呢?这是因为 Vue 和 React 设计理念上的区别,Vue 使用的是可变数据,而React更强调数据的不可变。所以应该说没有好坏之分,Vue更加简单,而React构建大型应用的时候更加棒。

Vue中默认是支持双向绑定的。在Vue1.0中我们可以实现两种双向绑定:

  • 父子组件之间,props 可以双向绑定
  • 组件与DOM之间可以通过 v-model 双向绑定

在 Vue2.x 中去掉了第一种,也就是父子组件之间不能双向绑定了(但是提供了一个语法糖自动帮你通过事件的方式修改),并且 Vue2.x 已经不鼓励组件对自己的 props 进行任何修改了。
所以现在我们只有 组件 <–> DOM 之间的双向绑定这一种。

然而 React 从诞生之初就不支持双向绑定,React一直提倡的是单向数据流,他称之为 onChange/setState()模式。

不过由于我们一般都会用 Vuex 以及 Redux 等单向数据流的状态管理框架,因此很多时候我们感受不到这一点的区别了。

HoC (高阶组件) 和 mixins

在 Vue 中我们组合不同功能的方式是通过 mixin,而在React中我们通过 HoC (高阶组件)。

React 最早也是使用 mixins 的,不过后来他们觉得这种方式对组件侵入太强会导致很多问题,就弃用了 mixinx 转而使用 HoC,关于mixin究竟哪里不好,可以参考React官方的这篇文章 Mixins Considered Harmful

而 Vue 一直是使用 mixin 来实现的。

为什么 Vue 不采用 HoC 的方式来实现呢?

高阶组件本质就是高阶函数,React 的组件是一个纯粹的函数,所以高阶函数对React来说非常简单。

但是Vue就不行了,Vue中组件是一个被包装的函数,并不简单的就是我们定义组件的时候传入的对象或者函数。比如我们定义的模板怎么被编译的?比如声明的props怎么接收到的?这些都是vue创建组件实例的时候隐式干的事。由于vue默默帮我们做了这么多事,所以我们自己如果直接把组件的声明包装一下,返回一个高阶组件,那么这个被包装的组件就无法正常工作了。

组件通信的区别

在Vue 中有三种方式可以实现组件通信:

  • 父组件通过 props 向子组件传递数据或者回调,虽然可以传递回调,但是我们一般只传数据,而通过 事件的机制来处理子组件向父组件的通信
  • 子组件通过 事件 向父组件发送消息
  • 通过 V2.2.0 中新增的 provide/inject 来实现父组件向子组件注入数据,可以跨越多个层级。

另外有一些比如访问 parent/parent/parent/children等比较dirty的方式这里就不讲了。

在 React 中,也有对应的三种方式:

  • 父组件通过 props 可以向子组件传递数据或者回调
  • 可以通过 context 进行跨层级的通信,这其实和 provide/inject 起到的作用差不多。

可以看到,React 本身并不支持自定义事件,Vue中子组件向父组件传递消息有两种方式:事件和回调函数,而且Vue更倾向于使用事件。但是在 React 中我们都是使用回调函数的,这可能是他们二者最大的区别。

模板渲染方式的不同

在表层上, 模板的语法不同

  • React 是通过JSX渲染模板
  • 而Vue是通过一种拓展的HTML语法进行渲染

但其实这只是表面现象,毕竟React并不必须依赖JSX。
在深层上,模板的原理不同,这才是他们的本质区别:

  • React是在组件JS代码中,通过原生JS实现模板中的常见语法,比如插值,条件,循环等,都是通过JS语法实现的
  • Vue是在和组件JS代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要 v-if 来实现

对这一点,我个人比较喜欢React的做法,因为他更加纯粹更加原生,而Vue的做法显得有些独特,会把HTML弄得很乱。举个例子,说明React的好处:

react中render函数是支持闭包特性的,所以我们import的组件在render中可以直接调用。但是在Vue中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以我们import 一个组件完了之后,还需要在 components 中再声明下,这样显然是很奇怪但又不得不这样的做法。

Vuex 和 Redux 的区别

从表面上来说,store 注入和使用方式有一些区别。

在 Vuex 中,$store 被直接注入到了组件实例中,因此可以比较灵活的使用:

  • 使用 dispatch 和 commit 提交更新
  • 通过 mapState 或者直接通过 this.$store 来读取数据

在 Redux 中,我们每一个组件都需要显示的用 connect 把需要的 props 和 dispatch 连接起来。

另外 Vuex 更加灵活一些,组件中既可以 dispatch action 也可以 commit updates,而 Redux 中只能进行 dispatch,并不能直接调用 reducer 进行修改。

从实现原理上来说,最大的区别是两点:

  • Redux 使用的是不可变数据,而Vuex的数据是可变的。Redux每次都是用新的state替换旧的state,而Vuex是直接修改
  • Redux 在检测数据变化的时候,是通过 diff 的方式比较差异的,而Vuex其实和Vue的原理一样,是通过 getter/setter来比较的(如果看Vuex源码会知道,其实他内部直接创建一个Vue实例用来跟踪数据变化)

而这两点的区别,其实也是因为 React 和 Vue的设计理念上的区别。React更偏向于构建稳定大型的应用,非常的科班化。相比之下,Vue更偏向于简单迅速的解决问题,更灵活,不那么严格遵循条条框框。因此也会给人一种大型项目用React,小型项目用 Vue 的感觉。

各自优点

React

  1. React速度很快:它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好。最大限度减少DOM交互。
  2. 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
  3. 一切都是component:代码更加模块化,重用代码更容易,可维护性高。这样当某个或某些组件出现问题是,可以方便地进行隔离。每个组件都可以进行独立的开发和测试,并且它们可以引入其它组件。这等同于提高了代码的可维护性。
  4. 单向数据流:Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。减少了重复代码,这也是它为什么比传统数据绑定更简单。
  5. 同构、纯粹的javascript:因为搜索引擎的爬虫程序依赖的是服务端响应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。
  6. 兼容性好:比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。

vue

  1. 性能高效
  2. 双向数据绑定
  3. 学习难度低,上手简单。

React 的缺陷

  1. React 只是一个视图库,而不是一个完整的框架。
  2. 对于 Web 开发初学者来说,有一个学习曲线。
  3. 将 React 集成到传统的 MVC 框架中需要一些额外的配置。
  4. 代码复杂性随着内联模板和 JSX 的增加而增加。
  5. 如果有太多的小组件可能增加项目的庞大和复杂。

9.Vue3了解吗?

在Vue 3中,你的API的使用将不是简单的通过导入Vue实例来使用这个API,每个全局API将会以exports的形式单独导出

基于Proxy的响应:在Vue 3中已经不再采用这种定义的方式,改用ES6中提供的Proxy这个API实现数据响应的功能。

新的组件渲染模式:在Vue 3中重新定义了渲染的模式,在重新渲染时不会重新渲染没有发生改变的组件,只会重新渲染发生改变的组件

在Vue 3.0中摈弃了2x中使用options创建组件的方式,改用Composition Api

10. vue的生命周期

4个阶段,8个生命周期函数

组件创建时(creating):beforeCreate created

模板渲染时(mounting):beforeMount mounted

数据更新时(updating):beforeUpdate updated

组件卸载时(destorying):beforeDestory destoryed

– 创建期间的生命周期函数:
+ beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
+ created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
+ beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
+ mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
– 运行期间的生命周期函数:
+ beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
+ updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
– 销毁期间的生命周期函数:
+ beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
+ destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

11. 导航钩子有哪些,他们有哪些参数?(导航守卫相关)

关于路由的生命周期函数(Vue-router)

主要分为两种:全局式 局部式

全局钩子函数:

beforeEach:所有路由切换时开始调用,最先执行

afterEach:每次路由切换离开时调用

局部钩子函数:

beforeEnter

局部单个组件:

beforeRouterEnter

beforeRouterUpdate

beforeRouterLeave

完整的导航解析流程:

  1. 导航被触发
  2. 在失活的组件里调用离开守卫
  3. 调用全局的 beforeEach 守卫
  4. 在重用的组件里调用 beforeRouteUpdate 守卫
  5. 在路由配置里调用 beforEnter
  6. 解析异步路由组件
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫
  9. 导航被确认
  10. 调用全局的 afterEach 钩子
  11. 触发 DOM 更新
  12. 在创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数

12.Vue双向数据绑定原理

采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

<div id="app">
    <input type="text" id="txt">
    <p id="show"></p>
  </div>
  <script>
    var obj = {};
    Object.defineProperty(obj, 'txt', {
      get: function () {
        return obj;
      },
      set: function (newValue) {
        document.getElementById('txt').value = newValue;
        document.getElementById('show').innerHTML = newValue;
      }
    })
    document.addEventListener('keyup', function (e) {
      obj.txt = e.target.value;
    })
  </script>

13.路由懒加载的原理?

为什么需要懒加载?

像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的白屏,即使做了loading也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时

_webpack_require_.e方法是实现懒加载的核心,在这个方法里面处理了三件事情。
使用JSONP模式加载路由对应的js文件,也可以称为chunk。
设置chunk加载的三种状态并缓存在installedChunks中,防止chunk重复加载。
处理chunk加载超时和加载出错的场景。

14.Vue-router的模式和原理

hash模式

hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件

window.onhashchange = function(event){
 
    console.log(event.oldURL, event.newURL);
    let hash = location.hash.slice(1);
    document.body.style.color = hash;
 
}

history模式

因为HTML5标准发布,多了两个 API,pushState() 和 replaceState()。通过这两个 API (1)可以改变 url 地址且不会发送请求,(2)不仅可以读取历史记录栈,还可以对浏览器历史记录栈进行修改。

除此之外,还有popState().当浏览器跳转到新的状态时,将触发popState事件.

修改历史状态

包括了pushState,replaceState两个方法,这两个方法接收三个参数:stateObj,title,url

window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)

切换历史状态

包括back,forward,go三个方法,对应浏览器的前进forward,后退back,跳转go操作。 有同学说了,(谷歌)浏览器只有前进和后退,没有跳转,嗯,在前进后退上长按鼠标,会出来所有当前窗口的历史记录,从而可以跳转(也许叫跳更合适):

  1. history.go(-2);//后退两次
  2. history.go(2);//前进两次
  3. history.back(); //后退
  4. hsitory.forward(); //前进

区别:

  • 前面的hashchange,你只能改变#后面的url片段。而pushState设置的新URL可以是与当前URL同源的任意URL。
  • history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误

当用户刷新页面之类的操作时,浏览器会给服务器发送请求,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

history模式怕啥
不怕前进,不怕后退,就怕刷新,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的。

在history模式下,你可以自由的修改path。history模式最终的路由都体现在url的pathname中,这部分是会传到服务器端的,因此需要服务端对每一个可能的path值都作相应的映射。

当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。

15.keep-alive和对应的生命周期函数

当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated

keep-alive 提供了include和exclude两个属性,允许组件有条件的缓存

实现原理是在created的时候,将需要缓存的vnode节点放到cache中,在render是,根据name再进行取出

16.vue组件中怎么批量获取使用vuex的getters的多个值??

mapGetters?

17.终止请求和请求超时的方法

当前端请求发送并且响应未完成时,终止请求,不再返回数据

1、Axios 提供了一个 CancelToken的函数,这是一个构造函数,该函数的作用就是用来取消接口请求的。利用axios请求的config参数,向axios添加一个包含cancelToken的config配置对象。

当前端请求发送并且响应未完成时,用时太长,终止请求,不再返回数据

2、请求超时的设置。示例:

 axios.get('http://xxx.com/index/index', {
  		timeout: 300000  //这里来设置请求超时的时间
    })
  }).then(res => {})
  .catch(err => {
	console.log('数据请求超时')
  })

18.Vue传值方式

六种传值方式为:

  • 属性传值 父传子
  • 发布订阅 EventBus 子改父 o n / on/on/emit
  • Provider/inject
  • slot
  • $refs
  • p a r e n t / parent/parent/child
  • 本地存储 vuex localStorage
  • 路由传值

属性传值

1.可传值类型

  • 固定值
  • 绑定属性
  • 方法
  • 本类对象

2.操作步骤

①.父组件调用子组件的时候,绑定动态属性

②. 在子组件里边通过props,接收父组件传过来的值

3.适用场景

仅适用于 父组件给子组件传值

$refs传值

父组件通过$refs获取子组件的数据和方法

1.可获取类型

  • 子组件属性
  • 子组件方法

2.操作步骤

1.调用子组件的时候调用一个ref

2.在父组件中通过
this.r e f s . h e a d e r . 属 性 t h i s . refs.header.属性 this.refs.header.属性this.refs.header.方法

3.适用场景

子组件给父组件传值

$parent

子组件通过$parent获取父组件的数据和方法,这种传值方式实际上类似于上边的属性传值中父组件给子组件的传递了子类对象this,只不过Vue官方给封装好了。

1.可获取类型

  • 父组件属性
  • 父组件方法

2.操作步骤

直接在子组件中使用this.$parent.XX,不需要做任何多余操作。

3.适用场景

父组件给子组件传值

通知广播

1.可传值类型

Vue官网只写了[...args],故通知/广播传值我们定为只传基本数据类型,不能传方法。

2.操作步骤

1、新建一个js文件 然后引入vue 实例化vue 最后暴露这个实例

2、在要广播的地方引入刚才定义的实例

3、通过 VueEmit.$emit(‘名称’,‘数据’)传播数据

4、在接收收数据的地方通过 o n 接 收 广 播 的 数 据 V u e E m i t . on接收广播的数据 VueEmit.on接收广播的数据VueEmit.on(‘名称’,function(){})

3.适用场景

适用于父子组件、兄弟组件间进行传值。

本地传值

本地传值方式对于Vue而言有两种,一种是JS的localStorage,另一种Vuex

路由传值

1.父组件push使用this.r o u t e r . p u s h 2. 在 子 组 件 中 获 取 参 数 的 时 候 是 t h i s . router.push 2.在子组件中获取参数的时候是this.router.push2.在子组件中获取参数的时候是this.route.params

19.computed和watch的区别

计算属性computed :

  1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
  3. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

1.不支持缓存,数据变,直接会触发相应的操作;

2.watch支持异步;

3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;

  1. 当一个属性发生变化时,需要执行对应的操作;一对多;
  2. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,

immediate:组件加载立即触发回调函数执行,

deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。这是和computed最大的区别

20.axios实现拦截的原理

  1. 关于拦截,这里只说原理,前端的请求,最终还是离不开 ajax,像vue 的 vue-resource 、axios,都只是对ajax进行了统一的封装,它暴露出来的拦截器,其实就是写了一个方法,把ajax写在这个方法里面,(我们先说请求拦截器哈)在执行这个方法的时候,先将请求时要添加给请求头的那些数据(token、后端要的加密码…具体要看实际情况)先执行一遍,都赋值给一个变量,然后再统一传给ajax,接下来就是执行ajax,这就是所谓的请求拦截,其实就是先执行要添加的数据,然后再执行ajax,如果把这个添加数据的过程抽出来,就成了所谓的请求拦截器;
  2. 响应拦截器:响应拦截器也是一样如此,就是在请求结果返回后,先不直接导出,而是先对响应码等等进行处理,处理好后再导出给页面,如果将这个对响应码的处理过程抽出来,就成了所谓的响应拦截器;

21.微信小程序生命周期

分为应用生命周期页面生命周期

应用生命周期

属性类型默认值必填说明
onLaunchfunction监听小程序初始化。
onShowfunction监听小程序启动或切前台。
onHidefunction监听小程序切后台。
onErrorfunction错误监听函数。
onPageNotFoundfunction页面不存在监听函数。

页面生命周期

属性类型说明
dataObject页面的初始数据
onLoadfunction生命周期回调—监听页面加载
onShowfunction生命周期回调—监听页面显示
onReadyfunction生命周期回调—监听页面初次渲染完成
onHidefunction生命周期回调—监听页面隐藏
onUnloadfunction生命周期回调—监听页面卸载
onPullDownRefreshfunction监听用户下拉动作
onReachBottomfunction页面上拉触底事件的处理函数
onShareAppMessagefunction用户点击右上角转发
onPageScrollfunction页面滚动触发事件的处理函数
onResizefunction页面尺寸改变时触发,详见 响应显示区域变化
onTabItemTapfunction当前是 tab 页时,点击 tab 时触发

22 Vue插件

什么是vue插件

官方解释

插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

  1. 添加全局方法或者属性。如: vue-custom-element
  2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch
  3. 通过全局混入来添加一些组件选项。如 vue-router
  4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

通过全局方法 Vue.use() 使用插件。它需要在你调用 new Vue() 启动应用之前完成

为防止 多次注册同一个插件: 我们可以传递一个可选的对象

Vue.use(MyPlugin, { someOption: true })

Vue.use 会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件。

还用过哪些插件?

qs库 ElementUI

vue-datepicker – 日历和日期选择组件

vue-region-picker – 选择中国的省份市和地区

vue-baidu-map– 基于 Vue 2的百度地图组件库

lazy-vue – 懒加载图片

axios Vuex

等等等等

23.项目中如何封装一个组件

1.首先对这个组件的要实现的功能需求进行分析

2.然后定义一个.vue结尾的文件

3.在文件中添加

4.完成需求的相关功能,留好插槽

24.Vue路由懒加载的实现方式

1.vue异步组件

/*每个组件生成一个js文件,实现组件的懒加载*/

{
    path: '/path',
    name: 'componentName',
    component: resolve => require(['@/componentPath'], resolve),
  }

2.import按需加载(官方写法)

能够被webpack自动代码分割

允许将不同的组件打包到一个异步块中,使用命名chunk(特殊注释语法)。

Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

const comA = () => import('url')
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

3.webpack提供的require.ensure()

vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。

这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

{  
    path: '/home',   name: 'home',   
    component: r =>require.ensure([], () => r(require('@/components/home')), 'demo')
 }

25.项目中遇到过什么问题?

1.在vue项目中关于定时器的使用(很恶心)

假如,我们在A组建中声明了一个定时器进行倒计时此时 我们在定时器中一直打印时间戳,此时我们通过路由跳转到下一个组件页面,按照正常理论来说,A组件在跳转后整个组件就会被销毁,到达B组件时A组件已经没有了。

但是在我们有定时器的情况下 此时跳转过后 定时器依然会存在。所以我们要在页面销毁时候将当前页面的定时器clear掉。

更多:Vue专题之难点突破

http://eyee21.php22.host357.com/js/478

新动向:一些人悄悄开始从Python转向Rust

Python毫无疑问是近几年最热门的语言,人工智能和大数据的兴起,让Python至今热度不减,然而事情却在起变化,有一些人,尤其是在研究前沿的科学家和工程师们开始从Python转向Rust, 理由是Rust提供更高的性能,尽管详细Python的学习难度大了不少。

新风向标:学术界开始从Python转向Rust

2015 年,德国生物信息学家约翰内斯·科斯特(Johannes Koster) 曾用 Python 编写了一个广受欢迎的工作流管理器 Snakemake。作为大家公认的“Python 专家”,目前他正在筹备一个新项目,该项目对性能要求较高,而他认为 Python 无法提供该项目需要的计算性能。因此,他开始寻求一种新的编程语言解决方案。

Koster 现在在德国杜伊斯堡-埃森大学工作,他对这门新语言解决方案的要求是:既要能提供 Python 的“表达能力”,也要拥有 C/C ++ 的运行效率。用他自己的话来说,它需要是“一种符合人类使用习惯,同时又具备高效性能的语言”。最终他选用的语言就是 Rust 。

Rust 最初于 2006 年由 Mozilla 工程师 Graydon Hoare 创建。Rust 融合了 C++ 语言的性能与其他高级语言优秀的语法特性,对代码安全性问题也进行了特别的处理,Mozilla 的火狐浏览器有一部分就是用 Rust 编写的,微软也正在用它重新编码 Windows 操作系统的部分内容。Rust 已连续 5 年在 Stack Overflow 开发者年度调查(今年调查了将近 65000 名程序员)中被评为 Stack Overflow “最受欢迎的” 编程语言。GitHub 上的数据也显示,Rust 是 2019 年平台上增长第二快的语言,比去年同期增长了 235%。

而在科学研究界,科学家们也正在转向使用 Rust。例如,Koster 利用 Rust 创建了一个名为 Varlociraptor 的应用程序,该程序将数百万个基因序列读数与数十亿个遗传碱基进行比较,以鉴定基因组变体。“这个项目的数据量是巨大的,”他说,“所以对性能的要求极高。”不过想要获得这样的性能也是需要付出一定的代价的:Rust 的学习困难度较大。

“使用 Rust 确实需要一些前期的学习时间,”卡罗•尼科尔斯(Carol Nichols)说。她是 Rust 核心团队的成员,也是位于宾夕法尼亚州匹兹堡的咨询公司 Integer 32 的创始人。“但它能帮我做一些我不能做的事情。我认为这段时间花得很值。”

避免无规则

通常情况下,当工作流中涉及到分析科学数据时,大家都倾向于选择使用 Python、R 和 Matlab 等语言。这些语言会逐一解释代码行,然后执行,这种编程风格有利于研究数据,但速度慢。

C 和 C++执行效率很高,但是他们“没有规则”,Ashley Hauck 说,他是斯德哥尔摩的一名 Rust 程序员(在社区中人称“Rustacean”)。例如,没有任何措施可以防止 C 或 C++程序员错误地访问已经释放回操作系统的内存,或者避免程序两次释放同一块内存。仅仅是导致程序崩溃还好,最糟糕的是,它还可能返回无意义的数据或暴露安全漏洞。据微软的研究人员称,该公司每年修复的漏洞中有 70%与内存安全有关。

遵守设计规则

Rust 的模型可以根据规则将每一块内存分配给单个所有者,并强制控制访问权限。违反这些规则的代码也不会导致崩溃,因为它们不会被编译到。马里兰大学帕克分校的计算生物学家 Rob Patro 解释说:“它们有一个基于生命周期概念的内存管理系统,该系统让编译器在编译时跟踪内存的分配、释放、谁拥有它、谁可以访问它。”“得益于语言的设计方式,大量的错误在编译阶段就会被消除。”

这样的设计也有利于在多个处理器上运行软件的安全性,比如,可以消除多个计算线程同时访问相同数据的可能性。

Rust 比较容易维护和调试,但难于学习掌握。“其它主流语言都没有这些概念,理解了这些概念才是真正明白如何使用 Rust 编写代码的真正核心。”Nichols 说。Stephan Hugel 在都柏林三一学院研究地理数据的可视化,他自己花了两到三个月的时间移植 Python 算法,将地理空间坐标从一个参考系统转换到另一个参考系统,从而使执行速度提高了四倍。加州拉霍亚市的化学信息软件公司 Metamolecular 的创始人理查德•阿波塔卡说,他花了大约六个月的时间才精通这门语言。

关注用户使用体验

“为了提高语言的影响力,Rust 开发人员着重对用户体验进行了优化。”Manish Goregaokar 说,他是 Rust 开发人员工具团队的负责人,现居加州伯克利。例如,编译器会产生信息特别丰富的错误消息,甚至会突出显示出错的代码并给出修复建议。Goregaokar 解释说:“既然给语言引入了一个新的功能概念,那么使用起来就要让人感到舒服。”

Rust 社区还提供了丰富的文档支持和在线帮助,其中包括一个名为 The Book 的在线参考文档和一个罗列常见问题的“Cookbook”问题列表。用户对 Rust 的工具链还是比较满意的,程序员可以用它来将代码转化为应用程序(可参考下文中的“构建 Rust 应用”)。“关于 Rust 的工具和基础设施建设完善度确实让人感到惊奇。”Patro 说。与程序员用来构建 C 代码的许多编译器和辅助工具不同,Rust 开发者可以使用一个叫做 Cargo 的单一工具来编译 Rust 代码、运行测试、自动生成文档、上传包到存储库等等,它还可以自动下载和安装第三方软件包。使用一个名为 Clippy 的第三方插件还可以标记常见错误和不建议使用的 Rust 代码,Patro 非常喜欢该工具。

构建Rust应用

下面介绍如何创建一个GenBank文件阅读器,以便你进一步了解Rust的特性

•从www.rust-lang.org/learn/get-started下载安装Rus

•到https://github.com/jperkel/gb_read克隆GitHub上的代

•执行‘cargo run’命令下载外部依赖项并构建应用程序。默认情况下,应用程序会解析GitHub仓库中GenBank文件’ nc_005816.gb’。你也可以使用“cargo run <filename>”来指定一个输入文件

•使用“cargo test”执行单元测试

•使用“cargo doc -open”创建和查看文档。

Rust 还为常用的开发环境提供了 Rust 插件,比如微软的Visual Studio Code和 JetBrains 的 IntelliJ,它还为Rust playground提供了一个实时的、在线的 Rust 开发环境。澳大利亚悉尼的软件开发人员大卫拉蒂摩尔(David Lattimore)还创建了一个在 Jupyter 计算笔记本中使用 Rust 的“内核”,以及一个名为 REPL( read-evaluate-print loop)的 python 风格的交互环境。

Rust 的第三方软件包生态系统可以辅助软件开发,目前第三方库数量已经接近 50,000(参见下图“Rust rising”)。它们封装了诸如生物信息学(Koster ‘s Rust-Bio)、地球科学(the Geo-Rust project)和数学(nalgebra)等学科的算法。尽管如此,Nichols 说,“如果你需要的库在 Rust 中没有,那肯定就会让人感觉不爽。”不过,程序员有时可以使用 Rust 的“外部函数接口”来弥补这一差距。

新风向标:学术界开始从Python转向Rust

Rust 代码优势

除了编码流程之外,更需要特别说明的是 Rust 的高效性能。今年 5 月,马萨诸塞州波士顿市达纳法伯癌症研究所(Dana-Farber Cancer Institute)的生物信息学家李衡(Heng Li)在一项计算生物学任务中测试了多种语言,该任务涉及解析 570 万份序列记录。Rust 超越 C,稳居榜首。“当你想要使用多线程编写高性能程序时,如果你需要它性能非常快,同时内存也很紧凑,那么 Rust 是理想的选择,”李说。

加州大学戴维斯分校的生物信息学家路易斯·艾贝尔说,用 Rust 重写了一个叫 Sourmash 的工具软件,它的主要功能是执行基因组搜索和分类分析,改用 Rust 后可以减少软件维护成本,使用较先进的现代语言特性,同时程序还可以通过 web 浏览器访问。他说。

Patro 的团队成员 Avi Srivastava 实习归来后,在研究生 Hirak Sarkar 的带领下,利用 Rust 构建了一个名为 Terminus 的基因表达分析工具,Avi Srivastava 之前在位于美国加利福尼亚州普莱森顿的一家生物技术公司 10x Genomics 实习,在那里他使用 Rust 开发开源工具。现在在纽约基因组中心工作的 Srivastava 解释说:“Rust 的优势在于高效的任务调试,因为 Rust 的内存管理做的非常好。”

对于许多 Rust 开发者来说,社区氛围因素也非常重要。Hauck 是 LGBT+社区的一员,她说 Rust 的用户已经用他们的方式让她感受到了热情。她说,“这个社区一直在坚持包容性,他们非常清楚多样性对事物的影响,非常清楚如何制定和执行行为准则。”。

“这可能是我仍然在使用 Rust 的原因,”Hauck 说。“它的社区建设太棒了。”

看完专家分享,再来看看各位工程师的反应:

風輕雲淡-鐡馬錔冰河19小时前
有这精力多整些华为鸿蒙系统用的东西吧。比从头学一门工作上不怎么用到的语言,关键是全英文,连蒙带猜学习难度加大。

回复 ⋅ 收起回复2

用户646098380362218小时前
鸿蒙也就是linux和安卓的变种,一样英文的。程序员为了一个公司而放弃整个行业生态,那是傻。

回复9

下雨天吃乌云16小时前
外行人的吐槽

回复7

懒的虫18小时前
鸿蒙用汉语么

回复0

断凌殇17小时前
鸿蒙不太可能用汉语,e语言之类的汉语编程效率有点低,对电脑资源占用较大//@懒的虫:鸿蒙用汉语么

回复2

不笑猫猫18小时前

回复2

Jerry66480911小时前
笑死了

回复0

creations2小时前
支持哄蒙系统

回复0

奔跑吧番茄君32小时前
大家都看了说煤炭更有效率的人一眼

回复0

用户369285907897814小时前
支持你去吧

回复0

骑兲15小时前
Linux 改个名字 叫鸿蒙

回复0

阿华205416小时前
鸿蒙在哪呢?

回复0

断凌殇17小时前
别闹了,汉语编程也是将汉语转为应用在编成

回复0

讲道理你们带不动我6小时前
外行还真敢吐槽

回复1

zxeoc17小时前
友商都会反串了

回复0

流氓锈才21小时前
php是世界最好的语言

回复 ⋅ 收起回复11

艾克牛16小时前
作为大量使用过C++、PHP、Python、GoLang的老年程序员,我要不怕喷的说:PHP绝对是世界上最垃圾的编程语言

回复2

creations2小时前
哪个最好//@艾克牛:作为大量使用过C++、PHP、Python、GoLang的老年程序员,我要不怕喷的说:PHP绝对是世界上最垃圾的编程语言

回复0

sc000001小时前
但是如果让我短时间内做个小网站,我依然用它。能满足需求什么技术都可以用。//@艾克牛:作为大量使用过C++、PHP、Python、GoLang的老年程序员,我要不怕喷的说:PHP绝对是世界上最垃圾的编程语言

回复0

V5—8715小时前
萝卜白菜各有所爱,用着顺手就是“最好”

回复1

彩云之南大老表15小时前

回复0

柳岸花开12315小时前
中文是世界最好的语言,中文编程也一样

回复 ⋅ 收起回复0

hahahahalehaha1小时前
你好,外行,又来指导内行了吗

回复0

LelI4小时前
如果 真: 打印(“你好,世界”); 不然: 打印(“世界,你好”)

回复0

柳岸花开1233小时前
//@LelI:如果 真: 打印(“你好,世界”); 不然: 打印(“世界,你好”)

回复0

晶嘤嘤敲可爱14小时前
用着英文键盘打着汉字编程

回复0

柳岸花开1236小时前
拼音键盘打汉字//@晶嘤嘤敲可爱:用着英文键盘打着汉字编程

回复0

史小明律师14小时前
Python转为Rust

回复 ⋅ 收起回复0

DrLeeand7小时前
律师编程?

回复1

潘多拉的魔盒194318小时前
我TM才刚开始学python

回复 ⋅ 收起回复13

雀巢冰激淋15小时前
python只是效率低,灵活性秒杀一切

回复2

秋名山修道工38分钟前
python从入门到放弃

回复0

没有什么5157分钟前
我他娘的也是刚开始

回复0

神烦鸭15小时前
刚学就劝你放弃系列

回复0

opera230415小时前
helloworld

来自阿里10年前端的感悟(讲话实录):十年前端做了什么,前端的未来

沉鱼——阿里10年前端,Node Web 框架 Chair 的核心开发、Basement Baas 服务的技术负责人、九色鹿的技术负责人以及现在云凤蝶的技术负责人,现蚂蚁集团的体验技术部做企业级应用设计研发平台 —— 云凤蝶的技术负责人。本文摘自她的分享,回顾和总结在阿里十年前端的经验和对前端的发展展望。

开篇——入职阿里前端

1、2009 年

我做前端这 10 多年来的感悟

先看一下 2009 年,国内成立了第一个前端团队。大家刚刚如果有留意到主持人的介绍的话,会发现其实我是 2008 年入职淘宝的。那么那个时候我的主管是怎么发现我的呢?我当时在一家公司里面工作,工作之余还写博客,还会画一些跟程序员相关的有趣的小漫画。我估计大概是因为漫画吸引了非常多的人的目标,然后就这样进了淘宝。

大家可以看一下左边这张图,是 2008 年中秋节时淘宝网的首页截图。在这张图上,我基本上是达到了人生的巅峰。大家不要误会哈,这不是我作为一个前端的巅峰,而是我作为设计师的一个巅峰。

当时才刚刚流行做节日 Logo 没有多长时间,那段时间正好我们的设计师没空,这个时候我们的部门老板就说了,沉鱼你会画漫画对吧?那你要不要给我们画个中秋节 Logo 呀?我想来想去,那就画吧!画了之后这个 Logo 就真的上线了,被非常多的人看到。这个绝对是我在前端这个行业里面,做为设计师的一个高光时刻了。

大家可能也觉得奇怪,你一个前端,你干嘛画画?实际上 2008 年我入职淘宝网的时候,淘宝是没有一个专业的前端团队的,所有的前端同学都在体验技术部,Title 应该是叫交互设计师,我们跟设计师是在一个大团队的。

实际上那个时候很多的页面布局还使用 table 这样古老的技术,使得我们的设计师中也有不少人能够自主做一些网页。那个时候前端的同学更多的是专注在像淘宝首页这样一些比较重要的页面上,而一些活动页面之类的,就会由设计师同学从头至尾地完成。

直到 2009 年年初的时候,我们公司才正式划拨出了一个前端团队,据我所知也是国内第一个前端团队。于是 2009 年我们才正式有前端这个行业。

大家看一下右边的这张图,是我刚刚截的淘宝网现在的首页。如果我们仔细地看一下这两张页面,会发现除了页面变得更宽了、能适应更大的屏幕了、设计也更符合当下的审美了,似乎并没有发生什么太大的变化。

如果单从这两个页面来看的话,确实是这样,虽然我们使用了各种各样的新技术让页面浏览起来更加顺畅。但实际上前端的发展远不止于此。

2、2008 年 ~ 2012 年

我做前端这 10 多年来的感悟

其实任何一个行业在最初时期的发展都是非常慢的,所以在 2008 年到 2012 年这 4 年期间,前端的整体工作都非常的简单,我们可以简单地归结成为“浏览器大战”和“前端框架”这两个关键词。

“浏览器大战”可能对于一些比较新的同学来说,都已经不是很有体感了,因为现在 Chrome 一统天下,包括 2018 年微软也宣布了使用 Chromium 作为他们的浏览器的内核,所以 PC 时代的浏览器的兼容性问题已经彻底解决了。

但是在当时,大家对浏览器的兼容性问题是非常头疼的。

大家看一下左边这个图,有 10 来种浏览器,这还不是一个完全枚举。所以对于那个时候的前端同学来说,最头疼的事就是要处理前端兼容性的问题。而要命的是,当时 IE 仍然是市场上的主流,而且它作为一个主流,却又特别的不标准,性能也很差。

所以 Diss IE 也成为当时程序员的一个日常活动。中间这幅图当时是比较流行的一幅程序员漫画,大家可以看一下 IE 大概慢到了什么样的程度。因为当时的条件特别的恶劣,所以程序员在不断地跟这些我们现在看来有些可笑的问题做着斗争。

那个时候也是非常拓荒的时期,我们还缺乏一些基本的基础设施,前端框架就是非常重要的基础设施。那个时候,国内各大厂商都在开发自己的前端框架,在淘宝我就参与了 Kissy 的开发工作;实际上百度、360 以及新浪都有自己的前端框架。

当时这些大厂之间的前端交流是非常频繁的,所以在有一次交流之后,我回来就画了右边这幅漫画,调侃了一下当时各大厂的前端框架,没想到当时这幅漫画就成为了一个爆款,特别多的程序员看了这个漫画。

我们也觉得这种状态好像不是很正常,但是当时的前端并不像现在这样,有这么开阔的行业视野,所以大家在这个局里面困了挺久的。大家也看到,2008 年到 2012 年是整整 4 年时间,这 4 年不能说毫无发展,但是发展得真的非常慢。

3、2013 年

我做前端这 10 多年来的感悟

转机出现在 2013 年之后,我觉得整个前端行业走上了一个快车道。大家可以看一下左边的这张截图,一看就非常土,2009 年的一个手机淘宝页面,当然我当时有参与它的开发。

这么土的一个页面 —— 我们刚刚说 PC 时代结束了兼容性的问题,而移动时代其实才刚刚开始 —— 哪怕是 2009 年这么土的一个页面,它也有非常多的兼容性问题要考虑,可能都是大家意想不到的。

比如说,那个时候所谓的智能手机,其屏幕宽度差异是非常大的,我们为了确保每一行的文案都不折行,实际上需要采集当时市面上所有主流手机的屏幕尺寸,然后去做文案字数的适配。实际上在 2020 年,手机淘宝已经发展得非常好了,它跟 PC 没有什么太多的区别。

但我们的发展过程也不是一帆风顺的,特别是在早期的很长一段时间里,手机淘宝的地位可能都类似于一个附属品,或者说一个补充的存在。

直到 2013 年,整个公司都觉得这样下去不行了,我们必须要加速移动业务的发展。所以当时出了一个非常有名的事件,叫做阿里的“无线 All In”事件。当时公司调派了非常多的人员、资源去做无线手机淘宝。那一仗算是打胜了,胜得比较惊险。

但是要说业务真正地涨起来、形成 Mobile First 这样的用户心智,可能也要到 2015 年左右了。

当时有一件印象特别深的事情,因为我们的内网里有非常多的人,好几万人,所以大家也经常会在上面做一些自己的产品营销,几万人也是不能忽视的对吧~ 是在 2012 年还是 2013 年的双 11 大促的时候,无线手机淘宝的 PD 就在内网发言说今年双 11 大家都来用无线淘宝吧。

因为那个时候,不知道大家还有没有印象,秒杀特别火,就是一块钱秒一个特别贵的东西。我们无线淘宝的 PD 说来用无线淘宝的页面吧,咱们服务器水位低,秒杀一定不会卡。所以大家可想而知,在那个时候,哪怕是我们做成了“无线 All In”的那个时候,用户量也还没有大到一定的程度,但是趋势已经非常明显了。

而现在,大家基本上已经全部都是人手一个手机这样的情况了。在这个事情里面,我们很容易就能看到,哪怕我们在今天看来是一些巨变的事件的发生,也不是一朝一夕的事情。

就像我们在 2009 年的时候,就已经开始做手机淘宝了,到 2013 年无线 All In,再到市场完完全全以无线为主,这中间有足够多的时间去做出反应。所以很多的时候,我们只要踏准了时代发展的脉搏,就有足够的时间去做相应的对策

那么为什么说在无线端,浏览器兼容性的问题才刚刚开始呢?是因为一开始的时候,我们做的是 Native App,这个时候 iOS 跟 Android 的程序员是非常稀缺的。很多前端在这段时间里就转做了 iOS 跟 Android 开发。但是这两个领域吧,它们的人员培养成本非常高,而且研发成本也不低。

在现在这样飞速发展的时代,如果所有的东西都用这两个技术去开发的话,成本是非常高昂的。所以慢慢地 H5 又重新走上了历史的舞台。因为 Web 技术的成本特别低,所以我们尝试在无线的 App 里面加入 H5 的页面,来处理一些非核心页面的研发。

慢慢地,小程序又出现了,这个时候大家就已经知道了,今天的无线,真正重要的无线流量的入口没几个,而小程序就是非常重要的一个入口。

于是 Web 研发技术又重新回到了历史的舞台。当然最核心的那些 App 以及最核心的那些页面还是会用原生的 iOS 跟 Android 来开发。

大家可以看到,这个页面下面还放了一个 PWA,不知道有多少同学见过它,或者对它有体感。它是一个希望能用 Web 技术做 Native 应用的解决方案,是 Google 家的产品。到目前为止还没有看到 PWA 特别大规模流行的趋势,但它其实已经出来蛮多年了,大家可以关注一下。这几个技术的此消彼长,其实是蛮有意思的事情。

4、2015 年

我做前端这 10 多年来的感悟

时间飞快地来到了 2015 年,由于之前“无线 All In”的事情,从很多团队调派了人手,集中人力去做了这么一件大事,所以作为团队留守的一些成员来说是比较伤的,因为业务被裁撤,人员也减少了。

但是我们团队有一部分同学留下来了,我是其中之一,我们仍然在摸索 PC 端的一些可能性。这个时候其实新一代的研发框架已经逐步地生长起来了,最早的是 2010 年的 Angular 以及 2013 年 React.js 和 Vue.js。在这几个框架当中,我们并没有犹豫太久。

在 2015 年的时候我们团队就决定要使用 React。原因比较简单,因为 React 可能比 Angular 好用,比 Vue 灵活。但是这个不牵涉语言之争,仅仅是我们团队的一个选择哈。

在那个时候,我们并没有太长的时间去喘息或者迷茫,很快我们又忙起来了,为什么呢?因为 2015 年被称为 toB 元年,那一年发生了很多的事情,我们就发现其实 toB 的业务也非常地繁茂、非常地有前景。

所以这个时候我们也发布了我们第一个 toB 的 UI 组件库 —— Ant Design,简称 AntD。它从最初的一个非常单一的 toB 组件库发展到今天,已经集合了可视化解决方案、业务场景化模板以及 Mobile 组件库,变成了一个非常大的家族。

在去年的时候,我们的 GitHub 仓库的 Star 数也已经超过了 Google 的 Material Design,成为了 GitHub 上同类开源项目当中 Star 数最高的项目。Ant Design 对我们来说其实还是做得挺艰难的,从 2015 年开始一直到现在,我们还是在大力维护它。

这个项目的 Owner 就在我们隔壁组,叫偏右。我有的时候也会调侃他说,你说你们的 Ant Design 这么多人用,它的竞争力到底是什么?他就非常干脆地甩给我两个字:好看。

没错,很多时候我们常常强调要有大局观、要有全局的视野,但是细节也不能忽视,这个东西它真的好用,能契合到我们工作当中的一些场景,就非常地有生命力。

我做前端这 10 多年来的感悟

除了刚才提到的 toB 的前端框架,那段时间大数据也开始崭露头角了,所以相关的可视化的图形库也非常多,包括百度的 Echarts,蚂蚁的 DataV。最早的时候大家可能会用这些图表来做一些可视化的用户行为分析,包括 CNZZ 还有 Google Analytics 这样的东西。但是慢慢地行业就逐渐向深水区发展了。

在 Keynote 的右上角是我们的一个业务分析场景,这个场景特别复杂,可能会有数十万个节点要去操作,这样复杂的场景,又给技术带来了新的挑战,比如说:数十万的节点的计算如何保证性能,如何呈现能保证向用户有效地传递信息等等,这些新的问题都有待我们去解决。实际上我们的业务越来越复杂的话,就会推动技术进一步的发展。

而 Keynote 的右下角是一张非常漂亮的大图,是可视化发展的另一个分支,这个分支比较高端,叫大屏。大屏上的东西特别漂亮,一般来说大家会在企业的接待处或者政府机关看到这种大屏,它其实是有几面墙那么大的。它对视觉的要求是非常高的,大家可以看到它非常精细。

最近也在流行一个形容这一类大屏的词,叫做数字孪生,就是用数字化去打造一个跟我们生活当中一模一样的城市,通常都会用于做交通管控或者金融管控,这种时候大屏就会非常有用。这类大屏之所以足够特殊,就是因为普通的电脑根本就跑不起来,它是需要有特殊的机器来承载的。

刚刚说的这两件事,其实我是一行代码都没参与,都是我们隔壁组的同学做的事。

我做前端这 10 多年来的感悟

那这段时间我干嘛去了呢?我去做了这件事。因为随着 2009 年 Node.js 的发布,前端逐渐有了一些想象力,就是能够去做一些后端的事。倒不是说没有 Node.js 就做不了,你可以用 PHP,也可以用 Java,但是对于前端来说 Node.js 有天然的亲和力,因为用 Node.js 的话,你的前后端语言是一样的,有很多问题你自己就可以解决。

虽然 Node.js 一直都被作为一个玩具般的存在,但实际上它已经发展了很长的一段时间,包括 2010 年的时候 Express 框架发布、socket.io 发布,2011 年的时候 LinkedIn、Uber 上船,2013 年的时候 Ebay上船。2013 年还发生了一件比较特殊的事情,那就是激进派的 Web 框架 Koa 诞生了,它的诞生给大家带来了一些新的思路和启发。所以我们团队在 2014 年的时候就开始计划要去做一个 Node.js 企业级的 Web 框架。

大家看中间的这一张图,这是我们当时的代码提交的记录图,可以看到至今还是非常活跃的。这个框架叫做 Chair,我在这个框架里面主要是参与打通跟现有技术体系的连通的这一部分。下面的叫做 egg,是 Chair 的一个开源版本,也就是说对于其他公司的同学来说,如果他想用这个东西的话,他可以基于 egg 来做自己的企业级 Web 框架。那么在这个框架上,我们的第一仗是什么呢?在当时流量最 Top 的支付宝收银台页面上,我们把它用上去了。

实际上这个过程是非常坎坷的,首先有非常多的技术问题要去解决,比如性能、安全性。比如说你说性能不好对吧?实际上 Node.js 非常擅长的就是 IO 密集型的处理,所以我们可以去做 Benchmark,看看到底是 Java 的性能好,还是 Node.js 的性能好,这些问题都是相对容易解决的。

比较难的是,当时我们是没有一个配套的研发流程的;我们也需要融入现有的研发体系,因为现有的研发体系完全是寄生在 Java 之下。其实很长一段时间里,前端都没有自己的发布流程,前端同学写完了一个模板语言之后,他需要把脚本提交到仓库里面,由 Java 的同学去做最后的发布。

另外还有一个更深远的问题,那就是要考虑相关研发人员的培养。因为大家都知道,在大学里面大家都是受过相关技能教育的,所以对于学 C、学 Java 的同学,他可能从学校一毕业出来就带着这样的技能;但是到现在为止 Node.js 也不是一门大学里的常驻课程。所以这个非常难。

当时这件事难点非常多,但是其他的就不细讲了,就讲讲当时我参与的那部分工作。当时我主要是做了两类工作。

一类是跟现有的 Java 服务打通的工作,跟 Java 服务打通是非常麻烦的事情,你经常需要去解析它的 RPC 请求,你需要知道它的协议是什么…… 所以在这段时间里,我写了很多的协议解析代码,包括一些像 Java IO 这样的协议解析,让它能够真正地跟 Node.js 端连通起来,让我们能够真正地连上生产端的各种各样的服务。

另外一个当时非常现实的困难就是,我们除了现在在 Keynote 上看到的这个支付宝收银台页面,实际上还有大量的业务,如果我们希望这个东西能够大量使用的话,我们不能把这个业务里面的代码全部推倒,都重新手写一遍,我们不能这样折腾这个业务。

当时我们在 Java 体系里面使用的是一个叫 Velocity 的模板,这个模板它坏就坏在它太灵活、太高级了,它跟现在的 Vue 这样的模板语言是完全不一样的东西。它可以说是非常接近编程语言的一个模板语言。那怎么办呢?

当时我们就写了一个转换解析器,把 Velocity 的模板语言转换成了 nunjunks 的模板,实际上 Velocity 模板语言的能力是 nunjunks 的超集,我们在转换过程中,还做了非常多的功能检查,在转换完成后,还会提示开发者在这个过程中发现了多少问题是需要人工转换的。

通过这样一系列的努力,我们能够真正地在既有体系里面跑起来了。所以如果大家做一个新东西时希望证明自己的话,最好的方式就是去做一个标杆项目。当时我们拿流量最高的支付宝收银台页面去做,还好最后做成了。2014 年的种子在后面就开花结果了,到了 2015 年的时候,这个框架基本上受到了比较广泛的认可。

我做前端这 10 多年来的感悟

其实 2015 年还发生了很多的事情,大家可能也不是很记得。其实 2015 年也是钉钉发布的第一年,在这一年里,有一个关键词叫做 Electron,Electron 是一个能让 Web 开发的同学用 Web 开发相关的技术做 Native 应用的一种技术,它最早其实是 GitHub 的 Atom 编辑器的副产品 —— 它一开始确实是个副产品,而后面就变得独立起来了。

在这方面有两个我觉得比较好的应用:一个是支付宝的小程序 IDE,它最早也是用 Electron 来开发的;一个就是我们的钉钉。大家都知道其实很多开发钉钉的同学,早期都是做“来往”的,所以里面有非常多前端的同学。后来大家转向钉钉之后,要做 Native 的App,大家是没有那么多的经验的,人又特别缺乏,我们又希望能够尽快做一版出来校验一下,看看是不是能得到市场的认可。

所以那个时候一帮前端同学就用 Electron 技术把钉钉的第一版给做出来了。虽然最终钉钉的版本还是换成了 Native 的版本,但是实际上 Electron 的版本也运行了很长一段时间,直到最后被大家反馈有比较多的性能问题。

但是实际上这也是见仁见智的,很多时候大家在说了一大串性能有问题的时候,我们经常会举一个例子:你去看看 VS Code,VS Code 慢吗?VS Code不慢,VS Code 可是用 Electron 来做的。所以很多时候我们也要看这个技术到底被用得怎么样,这也是很重要的。

我做前端这 10 多年来的感悟

2015 年还发生了这件事,如果不提那就肯定是漏掉了。Alpha Go 掀起了一场全民人工智能的浪潮,这波浪潮直到今天还在继续。其实早在 2015 年的时候,我们就有一些团队在跟进这个领域了,但是这里我要说的是,人工智能研究和人工智能应用完全是两件事。

如果想要做人工智能研究的话,基本上除了重新回去读个书可能还有点机会之外,剩下的应该就没机会了。因为这个行业的竞争其实非常激烈,绝对得是人中龙凤 —— 这个词用得一点都不夸张,一定是人中龙凤才能来做这件事。

但人工智能应用会越来越广泛,它的门槛也会越来越低。我们在这方面做了一些应用上的尝试,包括 2015 年阿里的智能设计平台,以及 2018 年的智能设计稿转代码平台。这两个平台都是贴着营销大促这个场景在跑,因为当时在双十一或者 6.18 大促期间的 Banner,或者这种推荐产品的图,它们的量级已经达到了上亿级别,这已经根本不可能靠人工去做了,所以我们只能向技术要产能。

所以大家想到了这样一些办法。还有一个就是我们团队现在在做的,蚂蚁企业级应用设计研发平台。可能大家会说,这看起来不就是一个 IDE 吗?它是怎么个人工智能法呢?这里我们先按下不表,待会再说。

5、2018 年

我做前端这 10 多年来的感悟

2015 年真的是技术发展非常蓬勃的一年,当然虽说很多技术可能在更早的时间 —— 比如说 2008年、2009 年 —— 就已经出现了,但是对于我而言,我觉得特别重要的那些技术,可能都是在 2015 年、2016 年那两年感知到的,那个时候技术真的是出现了一个大爆发,而且出现了非常多的能很好地落地到业务里的应用。这些技术现在仍然还在发展,但是近几年非常繁荣的可能是我们的 Web IDE 和 Web Editor。

这是我截的一个我们公司内部的一些相关产品的图,非常多,至少有 10 个,肯定还有很多我不知道的,就像前一个分享讲师讲的他们的 IDE,那个我就不知道。

大家可以从左到右看一下,最早的是大屏可视化数据分析类的产品,这个是跟着大数据的浪潮来发展起来的;然后到中间人工智能的这一波浪潮,Data Works 大数据开发以及 Pai 人工智能可视化开发;到第三列的支付宝小程序 IDE 和我们的 H5 & 小程序建站 IDE,最年轻的两个 IDE 是我们的 Cloud IDE 也就是云 IDE,以及云凤蝶企业级应用设计研发平台。

除了这些程序向的 IDE 之外,还有一些其他的复杂 Editor 的出现,即下面以语雀为例的富文本编辑器以及电子表格等。所以如果我们今天回头来看整个前端的发展,会发现实际上是非常迅猛的。很多工作年限比较短的同学,甚至都无法想象在 2008 年我们前端面临的是那样的一个场景。

所以业界不是有句名言嘛,说凡是能用 JavaScript 做的东西,最终都会用 JavaScript 做一遍,包括现在的 IDE 都是用 JavaScript 在写了,所以还挺神奇的。

6、2020 年

我做前端这 10 多年来的感悟

大家可能会说,你们前端这么牛,你们怎么不上天?其实确实上天了,大家可以看一下,2017 年 NASA 就已经上船 Node.js 了;在刚刚过去的 Space X 的发射中,大家也发现他们使用了前端的相关技术来做触控大屏。当然这条推文仅供大家娱乐一下,因为这条推文其实并不是 Space X 的工作人员发的,而是 Google 的一个程序员发的。

这里引发了大家比较多的讨论,我觉得有些回复比较有趣:有人说 node_modules 有没有让飞船超重啊?大家可以看一下截图的回复中间,有一个老爷爷,他其实是 JavaScript 的创始人,他仍然很活跃,经常做的事情之一就是反驳别人说 “JavaScript 就是个玩具语言”。这一页给大家娱乐一下。

发展到现在,其实我们会发现,首先前端的领域性越来越广了,在最初的前端行业里面,大家所要知道的东西就是 CSS、JavaScript、HTML,以及一些周边的东西,但是并没有像现在这样有那么多重要的东西能够去玩;另外一个是,它的难度确实是越来越高了,大家会发现整个前端的工作是一路向上延续的,从写页面到写编辑器,到移动端的浏览器内核,一路在向上,在向上的过程中对事情有更多的把控力。这两个趋势非常明显。

那么对于我们而言,我们要想的是,我们作为今天的前端,是不是可以满足于做的那些页面?答案肯定不是,我们要去看前端的后续发展中下一个浪潮在哪里,我们要踏对浪潮的脉搏,可能才会有更好的下一轮发展。

这个大概是我对前端过去这 12 年的简单总结。这个总结其实是非常个人的,有一些关键技术也没有出现在今天的分享当中,比如说 IoT,比如说 Web Assembly 等一些技术,相关的同学也可以去关注一下。

前端工作生涯的思考和感悟,希望有助于大家的工作、学习和职业发展

3、思考一:像做 PPT 一样做应用

我做前端这 10 多年来的感悟

首先大家都知道,可视化建站或者说可视化拖拽这个概念其实并不新鲜了,在八几年、九几年的时候,就已经开始有第一代产品在尝试了,但是无论怎样,几十年过去了,还有很多产品前赴后继地来做这件事,这说明了什么?

说明两个问题:一个是这个问题没有被彻底解决,否则就不会有那么多后来者;另外一个就是这个领域可能真的是有需求的,不然也不会有那么多人去做。

那么我们希望它到底“Low”到什么程度,它的门槛要低到什么样的程度才能让设计师和 PD 这样的角色能参与进来呢?我们首先定下来的原则就是,我们要像做 PPT 一样去做应用。什么叫像做 PPT 一样去做应用呢?

大家可以看一下左边这个小图,这个是市面上常见的一些同类产品的拖拽方式,这个拖拽方式是基于 Flex 布局的技术,所以当你拖出来一个东西到画布里面去的时候,通常只能上下位添加或者左右位添加。当你想要对这里面的东西做一些排版的时候,实际上是要经过一系列非常复杂的操作,才能够把它摆到想要的位置,这是现有的一些产品。

那么在云凤蝶上怎么做这件事呢?大家看一下,这个真的是像做 PPT 一样做应用,就是想摆哪就摆哪,没有什么布局的概念。

实际上这个技术并不算是云凤蝶的首创,因为在一些手机端的可视化建站产品当中,已经使用了这个技术,但是在手机端做这个事难度就低很多了。为什么说它难度很低?首先它不需要去考虑弹性布局的问题,因为手机端虽然说屏幕尺寸有一些差异,但只要做一个全屏幕的等比缩放这事就解决了,根本不存在布局问题。

而没有布局问题的话,我们也不需要去识别这些元素之间的父子关系。但是这两个问题在 PC 端都是非常大的问题,经常会有人开玩笑说,把一个专业的开发挡在前端门外的往往都是 CSS。这虽然是一句玩笑话,但也足以说明布局问题的复杂性。所以我们在布局的时候,需要考虑的问题非常多。

最终我们决定用这种非常简单的方式来让大家使用。比较眼尖的或者说经验比较丰富的同学可能会看出来,这个像做 PPT 一样的体验,效率是没有左边这张小图的高的,但是实际上是有解法的,而且我们正在解。

这就是我们整个产品的底座,它奠定了整个产品的基调。那么结果如何呢?结果就是大家确实买单了,不仅有前端的同学来用,还有后端的同学,更神奇的是,我们还发现有人拿我们这个做线上 PPT,很神奇,我们看了一下,做的还蛮好的。所以说,当你的产品力达到一定程度的时候,大家对这个产品的想象力可能会超乎大家最初对它的期望。

4、思考二:开放的组件体系

我做前端这 10 多年来的感悟

另外一个点就是丰富的精品 UI 资产。大家都知道我们在做应用研发的时候,最重要的两个东西是什么?一个是 UI 组件,另外一个是数据连接。

UI 资产其实就是 UI 组件这方面,通常来说同类产品做这个选择都会非常艰难,要么就是一个封闭的资产体系,也就是说我有 100个 组件,你就只能用这 100 个组件,而好处是这 100 个组件我会把体验打磨得非常好,而一旦组件不满足要求,那完蛋,只能退到 Pro Code。还有另外一种尝试叫做开放的组建体系,云凤蝶是走了这条路。

说到开放的组件体系,什么叫开放?意思是说凡是在 Pro Code 的世界里开发的组件,都可以通过简单的导入操作在云凤蝶里面使用。这个听起来非常的好,对不对?我们没有必要重复造轮子,所有在 Pro Code 世界里非常好的东西,我们都能拿过来用。

但实际上要让用户能够用得这么简单,难度是非常大的,因为一个小小的 npm 组件的导入,就有非常多的工作要做。比如说组件规范是什么?如何解析这个 npm 组件?解析后要不要做构建?构建!因为我们不可能像 Pro Code 里一样,在用户发布的时候说,等一等我跑个 10 分钟构建。

一般来说我们希望它是秒级发布的,所以我们需要提前把构建的工作做好。再比如一个 npm 组件的属性编辑怎么做?这些其实还都只解决了我们手工操作的问题。我们最终希望,一个 Pro Code 的同学,他每天写这些组件、发布这些组件,我们能不能让他发的时候就直接发到我们这个平台上来,这样的话无论是用 Pro Code 写代码,还是用云凤蝶做搭建,它都可以用,这是一个非常好的想法,所以我们最近也在做研发链路的打通。

在组件的世界里面,其实有一个最让大家头疼的事情就叫做版本升级,很多产品的版本碎片化非常严重,包括我们自己的 Pro Code 的很多组件库也是这样。

在云凤蝶中我们就定了一个原则,那就没有版本碎片,我们是强制用户升级的,我们用了一个 Codemod 技术,把所有的组件无缝升级了,用户看到提示的时候,只需要无脑点升级就可以。这其实是非常好的尝试,我们在这些尝试的过程当中,也跟 Pro Code 的同学有一些交流、沟通,甚至有一些反哺。

比如说后续 Pro Code 的同学可能也会尝试做版本的 Codemod,我们也能反推 Pro Code 的一些组件规范的提升。这个时候开放的组件体系就真正地把 Pro Code 跟 Low Code 融合在一起了,我们能够共享其中的产出。

5、思考三:数据驱动的智能研发

我做前端这 10 多年来的感悟

OK,说到了第三点,就是基于数据连接的智能研发,因为脏活累活、重复工作没有人想做第二遍,但现状是 —— 我不知道小厂怎么样 —— 反正我们大厂这类问题蛮多的,大家可能每天都在跟表单、表格做斗争,我指的是中后台业务线的同学们。

往往我们面临的业务还蛮复杂,有时候要做一个表单的话,往往是以星期为单位去计算开发工作量的。但实际上摸着良心问一问,做这个东西能有多大成就感?可能大家也觉得没有那么多成就感,对不对?毕竟还有那么多好玩的事。

所以我们就希望让机器去承担这一类重复劳动,包括设计。大家可以看一下我们现在在做的一个能力:这是一个表单,选择了一个 API 之后,你可以选择要填写的字段,然后它会根据 API 的元信息以及它的 API结 构自动生成这个表单。当然这是一个非常简单的演示,大家可以看到,该有的校验、排版之类的全部都是机器一键自动生成的。

我做前端这 10 多年来的感悟

所以这能给我们的整个研发带来非常多的便利、节约非常多的时间。但是它做起来也是非常坎坷的,因为大家都知道,一旦说到智能化,大家的想法是非常多的,有些人觉得是个银弹,也有人觉得不那么靠谱。

所以我们最初在决策到底用哪种智能化的方式的时候,也是经历过非常多的挣扎的。我们到底是从 API 直接到产物,还是去解析设计稿到产物?

最终我们决定从 API 到产物。为什么?因为中后台应用研发的设计是有一定的规范性的,我们并不会每天看到很多花里胡哨的中后台研发,而且在表单、表格这样的主流场景当中,涉及的规范性就更加明显了,没有那么多的设计创新。

另外,在 API 上有元数据的话,就有非常多的业务信息,这些是通过图片生成代码无可比拟的优势。而且还能省略设计师的设计工作。所以我们最后决定,直接就从数据接口生成产物。而在使用哪种 AI 技术上面,当时大家也是有过一些争议的,最后我们还是使用了专家系统这样的比较简单的方式,这个方式的效果是比较好的。

大家可以看一下,这张图是我们去年下半年的时候做的第一版技术原型,左边的是人工设计的版本,右边是云凤蝶设计研发的版本,大家会有比较明显的体感,会发现云凤蝶的版本更加精致一些。确实是这样,不是说人工设计的质量不好,而是 toB 的业务更多是理性的设计,要去做这个东西的话,往往可能有三、四百条设计规则在那等着你,作为一个人,是不擅长去记这些东西的,而这些恰恰是机器擅长做的。

比较搞笑的是,我们从去年年初的时候开始孵化,上半年产出的结果非常矬,后来下半年的时候,觉得这样下去不行了,得改进。然后就跟设计师一起想,我们才能怎么做到最好,把这事给做好。

当时在会议室里,我们就说这事要定个目标对吧?总得定个目标。没人发言,那我就说我们要不就定这样一个目标,我们把目标定成,产出结果比一般的人工设计师质量要高。这个时候大家都不说话了,都觉得这可是设计啊,这玩意怎么可能比人工设计要高,顶多接近它。

没办法,后来我们就说,那我们先接近人工设计的标准吧,后来过了一段时间,我们把技术原型做出来,也就是大家在 Keynote 上看到的这张图,顿时整个项目组的人都非常受到鼓舞。于是我们觉得,比人工设计的水准要高绝对是 OK 的。后来事实证明确实是这样,我们在业务当中确实很快就得到了业务的认可。

所以很多时候,大家想一些东西时,还是需要更大胆地去想。即便是设计这样非常有难度的东西,这些在我们看来最不可程序化的东西,也许也是有迹可循的。

6、思考四:混合模式

我做前端这 10 多年来的感悟

第四点讲一讲 Pro Code 跟 Low Code 的混合研发。很多时候像云凤蝶这样的 Low Code 产品,虽然我们想了非常多的创新点,想了非常多的解决用户痛点的点,但无论怎样,“你就是个拼多多,我就爱用天猫,我就不用你拼多多”。怎么办?这就不是技术问题了,这是一个用户信心建立的过程。

我们就做了一套方案,基于微前端的架构,把 Pro Code 和 Low Code 的应用给联合起来,作为一个开发者,他只需要随心地去选择合适他自己的研发方式就可以了。

我们看到下面这个是云凤蝶自己的一个产品页面,左边是我们的 IDE,是用 Pro Code 研发的,右边代表了所有一系列除 IDE 的其他页面全部都是用云凤蝶自举的。这个时候确实也不适合用某种单一的研发方式来完成我们的研发工作,而两者混合可能确实是最好的解决方案。这个解决方案实际上也解决了用户信心的问题。

比较有趣的地方是,一开始用户对我们信心不足,然后我们做了这个混合研发的架构,一段时间之后我们发现云凤蝶的智能表单、表格太受欢迎了,Pro Code 的同学也不想自己写了,他们说云凤蝶能不能做组件级的混合呀,在云凤蝶上的某个组件,能够嵌到 Pro Code 的代码里面去,Pro Code 的 npm 包也能嵌到云凤蝶里面来?

OK,这个事可以做,这个事做完之后就变成了什么?对你来说你无需考虑要选择哪种研发方式,而是考虑哪种研发方式对你的业务确确实实是最合适的。那些常规的工作,可能确实用云凤蝶就非常地快,能又快又好地做完。

虽然最初是因为用户信心不足,我们来做的这个事,但其实我们发现,当用户真正接受我们之后,100% 地使用云凤蝶来研发的项目是非常多的。除了像云凤蝶这样本身有那么一两个很特殊的 IDE 类的复杂度很高的页面,其他的页面都非常适合用云凤蝶这样的产品来研发。

7、对未来的思考

我做前端这 10 多年来的感悟

今天我在这里讲讲可能觉得还挺顺理成章的,但实际上过程是比较坎坷的,还不断地被拷问、被质疑,走到现在可能才刚刚好一些。而对于企业级应用研发 —— 我们内部经常会说中后台应用,这一类其实大家都知道,就像水面下的冰山,往往一个对外的页面对应的是好多个内部的系统,所以内部系统的量级是非常高的。而如果它有比较高的质量,其实对员工的工作效率有很大的帮助。

左边这张图就说明了适用云凤蝶的范围,我们把一个公司里面的应用分位两个维度来看,一个是它面向的用户规模,从小到大是团队级、部门级、企业级到 toC;另外一个维度是它的交互特殊性。黄色区域都是非常适合用云凤蝶这种研发方式来做的。云凤蝶其实在上面还有一部分是混合研发的,就是刚刚和大家讲过的。

那么对于未来的企业研发模式,我们认为它是怎么样的呢?就是右边这张图,上面是现状,有大量的 Pro Design、Pro Code。云凤蝶去年下半年发了第一个版本之后,去年大概有差一点不到 20% 的业务是由云凤蝶来承载的。

这对云凤蝶来说非常不容易,我刚刚讲了,我们上面有 OB 这样的业务在,所以要承载很多复杂应用的研发是很大的一个挑战。在去年数据里,有 40% 的产物是通过机器来做设计研发的,大概 60% 是人工。

我们希望未来大概是下面这张图的样子,首先 Pro Code 跟 Low Code 是能够进一步融合的,它们之间能产生实实在在的关联。

比如说能把 Pro Code 产出的组件放到云凤蝶里使用,同时云凤蝶也有非常多的天然优势,它能够非常精准地收集用户的需求以及用户的使用数据,能够给 Pro Code 的同学非常多的反馈,能促成一个良性循环。

慢慢地 Pro Design 和 Pro Code 的这些同学会去处理越来越复杂的场景,对于常规的研发工作来说,我们会慢慢收口到像云凤蝶这样的平台上面,并且未来在云凤蝶上可能有 70% 的工作是由机器去完成的,剩下的 30%,一部分是设计师来参与,一部分是工程师来参与。我们希望云凤蝶能够为中后台应用研发提效,让大家有更多的时间和机会去参与更加有挑战的事情。

好,这就是我近期的一些工作和有趣的事情。

四、一些感悟

我做前端这 10 多年来的感悟

接下来跟大家讲讲做前端的一些感悟吧,比较少哈。

我做前端这 10 多年来的感悟

1、认识自己

第一个是知道自己有什么、要什么、可以舍弃什么。在大家的提问里面,很多的同学都会关注自己要不要走管理,要不要学这个、学那个。实际上问题很简单,那就是你要什么、可以舍弃什么。

在我看来,管理是一件九死一生事情 —— 九死一生这词不严重。为什么我说它九死一生呢?因为至少 10 个人以上的团队才需要一个兼职的管理者,30 个人以上的团队可能才需要一个全职的管理者。当你进到管理行列的时候,完全是在另外一个赛道,可能跟你做技术的时候是两码事。

比如说要考虑到大家怎么开心地工作、团队怎么建立、末位怎么汰换、怎么给团队立下发展方向、怎么向上沟通汇报。这个时候很多同学可能会说,我们团队发展得比较快,没有人带团队,那我就得带;或者说我不带团队的话我技术不行,我怎么办呢?

大家自己想清楚自己要什么就好了,如果仅仅是因为觉得不带团队了可能就没有前途了之类的,其实并没有这个必要。我们团队就有非常多的高 P 的独立研发者在公司里面工作,工作得非常好、非常开心,他们也没有带团队,这其实是看个人的发展的。而且如果带团队让你感觉很痛苦的话,可能确实不带团队会比较好一些,这是第一点。

2、发现和定义问题

第二点就是学会发现问题、定义问题,至于怎么解决可以慢慢学。作为程序员,我们很多时候都是解决问题的角色,我们学的都是解决问题的方式方法。但是很多同学 —— 特别是有了一些工作年限的同学,他们在工作的过程当中会慢慢地发现,很多时候发现问题和定义问题会更加重要。

打个简单的比方,刚刚我在说为什么要去做云凤蝶?因为我们有一千多人的前端,有 1/3 在做中后台应用,急需解决研发效能的问题以及门槛的问题。那么说 1/3 的人在做这个事,其实还是挺有体感的,但是如果你跟老板说,我觉得现在前端研发的同学效能太低了,这句话可能很难让老板 Get 到这个事。

所以怎么去描述问题很重要,包括怎么去发现问题,因为很多的时候越往前走,你会发现问题就不那么明显了,甚至有可能很多时候大家都觉得这不是一个问题,直到你做出来了,他们才说原来你这个真的是很能解决问题的东西呀。这个过程当中,你可能经常会被别人 Diss 或者会被怀疑,但是如果真的想清楚这事应该怎么做的话,可以坚定一些。

3、注重基础

第三个是形成自己的知识体系,注重基础知识的积累。这是我觉得对工作年限比较短的同学来说最重要的事情。对于程序员来说,我们还是要去把本职工作做好,把基础打好,因为如果基础不好的话,走到管理岗可能也只是一种偶然,很难走长远。

在知识体系里面,有一些是基础知识,有一些是应用级别的知识,应用级别的知识就是你可能花两三个月、快的话两三个星期也能上手的这类。但要能识别出来哪些是基础的、哪些是应用的。对于基础知识可能往往要花非常多的心力或者精力去学习,但是一旦你学会了之后,它可能会让你在很长一段时间里都能受益。

4、无心插柳

第四点就是学点无用的东西、做点无用的事,见见无用的人。

这个可能跟前面的鳗鱼小姐姐的说法有一定等同,就是你现在做的这些无用的事,在未来总会连成一串。确实是这样,我回想了一下,在 2015 年参与开发 Chair —— 就是我们蚂蚁的 Node Web框架 —— 这个项目的时候,我做的几项工作。

第一个是打通了跟现有 Java 服务体系,能做成这件事,来源于我工作了之后还花了比较多的精力去学 Java。另外一个就是把当时 Java 的 Velocity 模板用机器编译成了 nunjunks 模板,这个正好是因为之前学了那本龙书 —— 叫《编译原理》的那本龙书,学完了之后正好就用到了,这个东西如果要想现学的话可能就比较难了,因为我当时断断续续看了半年。

这个仓库大家可以看一下,右边有一张截图,就是我当时的一些习题记录放在了 GitHub 上,很多同学在进入阿里之后就慢慢地不怎么更新了,我也是一样的,没办法,工作太忙了。但是这个仓库的 Star 数是一直在涨的,因为你可能找不到第二份习题答案。

今天趁着这个大会也想呼吁一下今天的听众同学,如果有同学对这个东西比较有兴趣的话,也欢迎成为这个仓库的维护者,因为我实在是忙到无力维护这个东西好多年了,但是我不断地看到有人在用,不断有人提 PR,我觉得荒废掉挺可惜的。

5、准求极致

第五点就是追求极致,最难的路可能是最好走的。如果我们选择了一条比较容易的路,我们往往会面临低质量的竞争;但是如果我们选了一条比较难的路,可能只是开始比较艰难,但是会越走越开阔。就像开始讲到云凤蝶在选择可视化搭建的画布基础的时候,我们选择了一个看起来可能最难的自由拖拽的画布,因为我们希望用户能够有一个像做 PPT 一样的应用研发体验,这个确实有非常多的技术难点要解决,当然这个过程当中 Bug 也搞了不少,也被用户骂了不少,但是做到今天,我们真正觉得这条路是走对了,而且我们不断地得到用户的认可。

五、书籍推荐

我做前端这 10 多年来的感悟

按照大会的惯例,需要给大家推荐一本书。我先说一下,如果大家觉得大学没有学好,那可能是因为教材比较渣,一定不要觉得是自己比较渣。这个我是深有体会的,因为很多大学的课程我在工作了之后又重新学了一遍,学的时候我就换了教材。

我做前端这 10 多年来的感悟

这是我给大家推荐的几本书。为什么是几本书呢?因为这些书其实是有一定的关联性的。

上面的三本是《微积分》、《线性代数》跟《概率论》,这个可能是我们所有同学在读本科的时候基础的三门课程。下面是大家可能会觉得现在比较热门的、同学们也比较想去了解的,是《数据挖掘》以及《人工智能》。

很多时候大家会看到有一些所谓的人工智能的入门书之类的,我建议大家如果真的对这两个东西感兴趣的话,可以看一看这两本书。这两本书都非常厚,但是《人工智能》这本书非常全面地讲述了人工智能领域所有的东西,当然有一些东西可能在今天看来比较过时,但仍然建议大家读一读,耐心一点把这本书读完。

这本书读完了之后,对人工智能能带来哪些好处,或者说哪个方案会比较靠谱一些,你就会有比较坚定的自己的看法,包括你要跟相关的同学去沟通,你是不会发怵的。

然后另外一个就是《数据挖掘》,现在大家都用数据说话嘛,所以数据挖掘也很重要。这本导论好就好在非常浅显易懂,基本上所有的方式方法你都能看得懂、用得着。所以这两本书非常推荐。

那为什么还推荐了上面的那一排基础书呢?因为在人工智能领域有一些基础的算法,可能让大家觉得最头疼的就是这些东西,正好上面的那本《线性代数》对应了人工智能行业非常多的基础算法,可以说是非常合适的一本人工智能算法基础的入门书。如果大家有兴趣的话,建议也看一看这本。包括上面的《概率论》也是一样的,因为在数据挖掘的时候,概率有非常大的作用。

好了,这就是今天我推荐的一些书,不要被这些书吓到,虽然看着都很厚,但是其实看着还挺有趣。

六、加入我们

好,到了最后了,这就是今天来跟大家聊的最大的动力,所以希望大家有什么问题的话也欢迎跟我交流。

七、Q & A

1、比较纠结,自己作为前端,不懂服务端的东西,而且平时工作也不太会涉及到服务端,自己想学一些服务端,但是又不知道如何下手,常常会陷入深深的自我怀疑,请问沉鱼小姐姐有没有一些好的建议?

如果是早期的前端,可能基本上都是从自我怀疑当中走过来的。我刚才讲过没有 Node.js 的时代,大家对服务端是很难插上手的。虽然可能有一部分同学会写 PHP,但是如果 PHP 没有用在你公司的生产环境里面,那也没有太多的用武之地。

我觉得比较靠谱的、比较有可操作性的两个建议是:

第一,看看你公司的整个服务端的架构是什么,然后可以学一学跟公司服务端架构贴近的东西,比如说你的公司用的是 Java —— 可能大部分公司都是用 Java,有一些创新公司会用 Node.js,那么那就学学 Java 呗。学一门语言在我看来是应用级别的东西,所以应该不会特别难才对。找到一些机会,然后学它、用它。

第二,我们要注重基础能力的培养,比如说你学 Java,到底知不知道一个 HTTP 请求是什么?HTTPS 请求跟它的区别是什么?最新的 HTTP2、HTTP3 到底是什么东西?因为这些东西包括多进程、多线程之类的,可能才是语言下面真正常用的那些知识。很多的同学在学语言的时候觉得晕,不是晕那个语言,而是因为那个语言下面那个知识可能不是很牢固。所以第二个建议就是去学习一下这些相关的知识。

然后第三个建议就见仁见智了,去更有挑战的地方。

2、你是如何掌握自己的时间的?如何掌握自己去学这么多东西?对于前端团队人比较少的情况,一般都是业务来推动开发,这种情况下应该如何去处理,逐渐让技术跟业务相互推动?

“掌控自己的时间”,首先还是不得不说一下,跟今天其他的分享嘉宾相比较而言,我的工作年限可能确实是比较长的,所以我就有更多的时间来学东西。你工作五、六年你肯定没有那么多时间学。另外一个,我确实比较珍惜早晨的时间,我通常会比较早就起。

如果平时我们公司 9:00 上班的话,我可能 6:30 到 8:00 左右之间,大概会有一个半小时的时间会持续地学习一些东西,这段时间一定是不会被干扰的,是非常高效的一段时间。当然现在说起来有点脸红,因为几年前我生了我们家宝宝,这个对女生来说确实会有一些影响,但是也没有太多的办法,只能不断地校准自己的时间。

“对于前端人数比较少的团队来说,通常都是业务推动开发”,对于大的前端团队来说也是这样的,没有太多的区别。只是大家在这个场景下怎么去看待业务,比如你能不能在现有的业务里面看到一些更远的东西,这个很重要。

其实我所在的团队可能是蚂蚁特别大的一个前端团队,但是也有一些团队是前端是比较大的,比如说我刚刚说的有一个大数据开发的 IDE,那个团队的同学,其实也是很厉害的,跟业务的大小有一定关系,但也并不是绝对的,有一些小团队他们可能做出来的东西也是很厉害的。

另外如果说,你实在觉得没有太多的发挥之处了,比如说你每天在家扫地,扫地机器人这玩意你要是能想到可能特别牛,如果要是想不到的话,可能还是在家每天扫地,觉得没有什么价值感,可能确实得停下来想想自己想做的这个事的价值到底是什么。最后如果觉得还是想不清楚,跟别人聊了也很迷茫的话,建议去看一看其他团队,那些你觉得做得特别好的、有活力的团队,他们是怎么做的,或者说换个环境也是 OK 的。

3、为什么是 API 到产物,而不是 UI 到产物?B 端跟 C 端的产品又有什么样的区别?

在我们公司内部有一个叫做 API 平台的东西,集合了公司所有能用的 API 以及一些 API 的元信息,这个元信息虽然说不全,但是在云凤蝶里面是能够补全的。元信息是什么?比如有一个叫做 userId 的字段,它可能是员工 id,当你有这样一些元信息的时候,你对 API 的理解就会更加丰富一些,你从这个 API 生成的产物,第一,它是集合了我们设计团队对整个设计规则的理解,也就是机器来做设计;第二,因为我们知道 API 上很多的元信息,所以更加能理解业务,能做出来直接可以做最后交付的东西。

如果说是 UI 到产物的话,那么你缺失了非常重要的业务信息,你只能根据它长什么样把这个页面切出来,但实际上没有办法完成功能的闭环,同时你还需要设计师先去做设计的工作。但问题也分具体场景,就是我刚才强调说,中后台研发不是对设计品质要求不高,而是对设计的特殊性、交互的特殊性要求不那么高,因为表单你不要做出一个花来对吧?这个时候 UI 到产物,它也有很多的应用场景,比如说我们在做一些促销的时候,推荐宝贝、推荐产品这样的东西,它的逻辑可能是偏少的,更多偏展示,这个时候 UI 到产物就比较好用。

B 端和 C 端的产品区别,笼统一点来说,我觉得 B 端的产品更多是完成功能性的需求,对于设计的特殊性要求是没有那么高的,但是并不意味着我们对品质的要求就低。因为你看我们有那么多对外的商业的 toB 的产品,那就必然意味着它的要求是很高的。

而且 B 端的逻辑可能复杂到难以想象,很多时候做 C 端的同学会觉得 B 端非常简单,就是做表单、表格,但是当你面临 800 个字段的表格、表单的时候,你要怎么搞?这个事情可能在 C 端是很难想象的。对于 C 端来说,它同样有非常多的挑战,比如说设计的新颖性、先进性,包括 C 端的体量非常大,这个体量可能是 B 端没有办法去比的,这就得具体问题具体看了。

4、身边的程序员是否都大部分都坚持了本行?有没有其他人转行的?转行的同学又是去做了什么?

我认识的大部分人可能都还是比较 Geek 的,所以很多人都还坚持在写代码的一线,包括一些高 P 的同学,也都在每天写代码。但是也有转行的,不是说程序员这条路一定要一条路走到黑,大家可以根据自己的规划去走。

比如说我们有认识的一些同学可能觉得,没问题,我到 P6、P7,我掌握了整个前端研发一些基础的东西之后,我出去创业,也有这样的同学,其实过得还挺好的,可能比我们要滋润很多。但这个就看个人选择了。还有一些做管理的,确实是少数,因为像刚刚说的,那个比例在那,比如说 30 个人才有 1 个管理者,这就意味着管理岗毕竟是很少的。

重锤!网信办专场整治8款手机浏览器,包括UC、QQ、360 、华为和小米,网友:该!

浏览器,PC时代的王者,曾经通向互联网世界的最大窗口。

而如今,因为移动互联网的发展,他可能成为一个远房亲戚式的存在,一年见不了几次面,人们几乎忘记它的存在。

网信办一次网络整治公告,网友们才惊呼:它还在!

没错,浏览器并没有变成历史的尘埃被扔进垃圾桶里,它还顽强的活着在你的周围,台前或者幕后,顽强正说明了它的处境艰难又尴尬。但跟人们最亲密接触的确实不是那个你曾经熟悉的PC浏览器,而是朝夕相伴的手机浏览器。

前几天国家网信办宣布的一项网络整治行动,几乎是手机浏览器“专场”。点名式的清单,包括移动互联网份额占比较大的UC、QQ、360和搜狗手机浏览器,也包括手机大厂自带的浏览器,包括华为、小米、vivo,oppo,总有一款你”被拥有“,所以这次整顿几乎覆盖了绝大多数用户。而整治就是人们深恶痛绝的包括「标题党」、低俗低质图文,视频以及谣言信息等内容层面的违规。

▲ 图片来自:The Conversation

其实用户苦手机浏览器的这些行为久矣!很多用户对手机浏览器的推送,无休止的弹窗,广告,低俗内容非常反感,尤其是设计个人隐私的事项,但也无可奈何,网友们看到这个整治活动,纷纷表示:该!

但原本只是用来浏览网页的浏览器为何变成这么臃肿,为什么这次会被”一锅端“,这些浏览器到底变成了什么样?是否真的这么惹人讨厌?这两天,有机构对这些浏览器进行了实际体验了,以证真伪。

几乎每个浏览器,都想成为一个今日头条

无休止的算法推荐

手机浏览器存在的问题,其实你一打开就可以发现了。

逐一打开小米、华为、OPPO、vivo、UC、搜狗、QQ 和 360 这 8 款手机浏览器,它们的首屏,无一例外都是以信息流呈现的,一路下滑,深不见底。

▲ 八款浏览器,傻傻分不清

越来越不象浏览器本该有的样子:如果不是还能在顶部看到搜索框,你可能根本不会觉得,这是一个浏览器应用。

在 26 号的整改通知下发后的隔天,这些浏览器就已经按照要求,在信息流顶部位置发布了《自查整改公告》。

▲ 整改公告发出的第二天,一些名单内的浏览器已经对信息流内容做了替换,只转载那些具有新闻采编权媒体的内容

与此同时,部分浏览器也对信息流内容进行了替换,只选用具有新闻采编权的媒体消息源,减少了花边新闻、明星八卦和自媒体消息的出现频次,但信息流中仍然保留了广告。

▲ 某个没有在首批整改名单之列的浏览器,则依旧充斥着很多标题党内容

但这些浏览器的信息流原来是什么样子的?我们找到了一款没有在本次整改范围内的手机产品,点开了它的自带浏览器,内容基本都是来自于自媒体了。

再往下刷几条,你又会看到熟悉的擦边球小视频,论质量,实在不敢恭维。

这也是大多数浏览器原本的画风:各种来自于不知名自媒体的图文信息,辅以夸张的标题,并夹杂着短视频、广告横幅页,而当年我们总喜欢调侃的「UC 震惊体」,在这些信息流中随处可见。

▲ 不管是自带的还是第三方浏览器,一旦打开推送,日常推送新闻的频次都非常高

这些浏览器的推送频次也非常高。只要你不关推送,哪怕是手机没开浏览器,静置个小半天,通知栏上也会堆积着各种新闻,可并不是那种非看不可的家国大事。

我们也就浏览器的推送问题询问了身边一些朋友,大部分人正因为不想被这些推送折腾,直接关掉了自带浏览器的通知权限。

信息流页面,还只是现在手机浏览器提供的其中一项功能而已。多数人吐槽浏览器「臃肿」、「杂乱」,是因为它们还做了很多本不该是浏览器需要做的服务。

▲ 八款浏览器都集成了视频、小说和游戏等功能,部分模块还直接放在了底栏

视频、小说、在线游戏,已经成为了现在浏览器应用的「标配」了,有的浏览器为了强调这些功能的存在,索性直接放在了底栏切换页上。

▲强行开启的「通知栏工具」,是一种比广告推送更为流氓的行为

我们还遇到了一种更明目张胆的做法:有两款第三方浏览器,都默认开启了「通知栏工具」的功能,实则就是在你的通知栏上显示搜索栏,或者快捷功能入口。

要是想去掉它,就只能手动去关闭。

▲ 手机浏览器的功能已经非常膨胀了,似乎就没有它不能做的服务

这么看下来,国内大部分主流手机浏览器,都已不再是单一的浏览器模式了。新闻、视频、小说、游戏等一应俱全,你甚至很难在市面上找到另外一种应用类型,可以在功能层面和浏览器媲美。

除了微信。

对比来看,浏览器原本应该做好的网页浏览,以及搜索,却被厂商所忽略,并逐渐变成了一个附属品功能,你很难说这是一个好的变化。

什么都想做,什么都不精;但如果不做,就无法提高浏览器的使用频次与黏性。

这或许是移动互联网时代下,每一个浏览器应用都在面对的困境。

浏览器有「焦虑感」,所以它才什么都想往里装

有人肯定会疑惑,同样都是浏览器,为什么像 Chrome、Safari 等应用,就不会有这些杂乱的东西?

这是不同的商业模式、产品定位决定的,对于 Google 和苹果而言,浏览器并非孤立存在,而是自家操作系统下的一款工具而已。浏览器本身没有盈利压力,那么就只需要做好浏览器该做的事情即可。

何况,这两款浏览器也有着同类应用所不具备的优势:Safari 背后有 iOS 和 Mac 系统,而 Chrome 则有 Android,光是预装在手机上这一点,就已经有着第三方浏览器难以企及的优势。

▲ 就全球来说,主流的浏览器依旧是 Chrome 一家独大,而 Safari 的占比很大程度上是由 iPhone 带来的

可第三方浏览器不一样。到了今天,单纯的浏览器已经很难再靠用户输入网址、打开页面作为卖点了。入口地位的下降,流量被瓜分,市场份额在面对巨头时,也难以有对策,就连原本浏览器最看重的「搜索」,很多人都已经习惯在微信、微博里完成。

你可能已经不记得,上一次主动点开浏览器是什么时候了。购物,你会找淘宝;打车,你会找滴滴;点餐,你会找美团… 我们的日常生活以及工作中的大部分需求,都已经被这些 APP 瓜分殆尽,且使用频次和时长,都远远超过打开浏览器。

▲ 其实主流浏览器都避不开信息流,Chrome 也做尝试

什么时候还会需要用到浏览器呢?朋友发来的外链在微信里打不开,你可能需要用它做一次跳转;要不就是碰到了某个知识盲区,想让搜索引擎拯救一下;还有人告诉我,他只有在连接公共 WiFi 时,才会想起主动点开自带浏览器,为的就是走一遍验证码流程。

浏览器的推送可以手动关闭吗?

以上讨论的场景都是被动产生的,如前文所说,若是想提升用户主动点开浏览器的欲望,信息流、游戏、文学等内容的分发,以及可以不断刷存在感的通知推送,都是简单直接,且成效更明显的做法。

▲ 这类开关都能在浏览器的设置项里找到,不想被推送骚扰的话,就全部关闭

这也是为什么有人说,浏览器的尽头,就是一个平台级应用与内容分发平台。

也正因为浏览器的定位逐渐模糊,它可以毫无顾虑地将各种服务都整合到一起,省去用户寻找、下载和使用其他 APP 的时间,为自己带来更多的流量。

此时,在抢占用户时间上,浏览器和今日头条、抖音这类应用并无多少区别了。

广告位肯定也是少不了的,只要能带来点击,那也代表会有更多的分成入账。

除了选择小众,你也可以手动精简浏览器

手机自带的浏览器并非无药可救,至少从我们体验的情况来看,大部分自带浏览器都内置了一个开关,它可能会叫「个性化推荐」、「资讯通知」,也可能叫「猜你喜欢」、「通知栏消息」,反正最终目的,都是为了给推送制造机会。

▲ 小米自带浏览器提供了一个简洁版主页功能

这些开关默认都是开启的,但你也可以手动把它们关掉,就能很大程度上解决自带浏览器胡乱推消息的毛病,摆脱信息过载。

但找出这些开关也需要花费一些心思,我们发现,有的浏览器直接将选项藏在了设置页面的二级菜单,甚至是三级菜单中,如果不逐条点开查看,很多人根本都不会知道。

▲ 搜狗、QQ 浏览器都可以关闭首屏信息流,但也仅限于此了

另外,个别自带、第三方浏览器也提供了首屏功能模块的自定义。比如像小米,自带浏览器就集成了一个「简洁模式」,开启后会直接关闭信息流、视频等分栏,只留下一个简版主屏,非常值得其他手机厂商借鉴。

而在搜狗、QQ 这两个第三方浏览器里,也都允许用户关闭首屏信息流,只是欠缺了一些美观度。

▲ 浏览器更应该做好哪些功能?一些小众化产品已经给出了答案

除了手动精简浏览器外,更多人还会投奔至一些小众浏览器麾下。现在的夸克、神奇、X 和 Via 等,都是在功能和设计上力求简洁的第三方浏览器代表。靠着视频下载、资源嗅探等插件,以及交互上的微创新,它们也从主流浏览器市场里争取到不少用户。 但这些小众浏览器能走多远,我们还不知道,毕竟借着预装的身份,以及众多的功能,大部分手机自带浏览器都不用太担心自己的流量,也不会有明显危机感。 只希望在本次整改后,主流浏览器漫天的信息流和广告能稍微收敛一些,或是至少提供一个清爽版开关,让我们拥有自行选择的机会。

手机浏览器不会消失,他会朝不同的方向发展,演化,但无论是哪种变化,请记得你应该有的样子,并让你的用户选择。

前端找工作的看过来:阿里2021年前端技术岗位发布(附内部面试题参考手册(含P5-P7))

毫无疑问,阿里巴巴是大部分技术er尤其是前端们最想去的公司,不仅因为薪水和大公司情节,更多在于阿里巴巴的技术体系已经在其优秀的产品和实战中得到了充分的展现,而在具体项目领域,Github上足以说明一切,再者,再马云的影响下,阿里巴巴是一家非常重视员工的企业,这也让很多人心生向往。

人们对阿里巴巴,对天猫,对淘宝,甚至对阿里云很熟悉,但是却很少人了解阿里内部的技术岗的体系结构,以及级别设置和对应的要求。因而只能有贼心,没贼胆,想去阿里面试但是心里没底。正所谓知己知彼,百战不殆,这篇来自前端教程公众号的文章“卧薪尝胆”,为大家整理了下阿里技术岗要求体系,最后为大家分享一份阿里在职面试官总结的完整面试题,希望对大家有著帮助!

岗位职级

阿里官方的定义是从P1-P14,11年以前还会招P4,之后就再也没有了,校招生都是从P5+起,社招P6起。

P5(高级研发工程师)

  1. 具有前端开发的工作经验,有大型系统的前端架构部署和实践经验。
  2. 熟悉React等主流Javascript框架,对它们适用的范围及优劣有独到见解。
  3. 了解至少一门非Web前端语言,对前后端合作模式有深入了解并有项目经验。
  4. 善于沟通,有良好的文档写作能力,口头沟通能力,良好的团队合作精神,良好的抽象思维,理性地做出技术决策,具有风险控制意识。

P6(技术主管)

  1.  前端技术扎实,技术专研能力强,对新事物和技术热情高,熟悉主流的思想;
  2.  在工程领域,前端框架(react,vue),全栈,移动,动画等领域有一项或是多项有深入研究(不仅仅只是使用);
  3.  执行力强,有良好的分析,总结能力。能够有效识别痛点,并找到有效的解决方案;
  4.  具备良好的团队协作精神,能利用自身技术能力提升团队整体研发效率,提高团队影响力;
  5. 在理解产品业务的基础上,提升产品的用户体验,技术驱动业务的发展。

P7(技术专家)

  1.  精通各种Web前端技术(HTML/CSS/Javascript等),熟练跨浏览器、跨终端的开发;
  2.  精通React、AngularJS、Vue等MVVM框架至少一种,并有在大型项目中使用的成功经验;
  3.  熟悉 Node.js Web 应用开发,有大型 Node.js 项目的开发经验;
  4.  熟悉 Web 安全相关知识,并能使用相关技术防范安全漏洞;
  5. 有大型网站前端架构、前端性能、可访问性、可维护性等方面的实践经验;
  6.  良好的项目管理能力,能独当一面负责一个大型项目的研发流程管理;
  7. 对前端技术有持续的热情,个性乐观开朗,逻辑性强,善于和各种背景的人合作;
  8.  至少熟悉一种后端开发语言,有后端开发经验者优先。

阿里P5-P7内部面试题(含答案):

因内容篇幅较长,更多资料欢迎持续关注。

精选GitHubs上star最多的100个前端项目(典藏)

GitHubs就不用说了,编程最新的实践都在这里,每一个星都是货真价实的认可,这里没有套路,只有实力。每个项目都汇聚了开发者的心血,这里挑出的100个前端项目,是社区上星标最多的,是最值得收藏,值得慢慢研究学习的,话不多说,上项目:

codepen 一个在线编辑前端项目的网站,其中有一些前端大神的作品,也有很多令人惊艳的前端效果,可以浏览和下载使用。codrops 一系列具有相当具有创意且有趣的前端效果的集合,是非常棒的学习资料,可以欣赏和下载使用。并且有些项目,也托管到了github仓库中docschina 印记中文网收集了由社区翻译的比较流行的前端相关框架、工具的中文版文档。为学习一些新的框架扫平了语言障碍。toby 超级赞的收集与协作管理书签的chrome插件,前端开发应该都会用chrome。全球超过10W+的用户。microjs 可以让你选择微型的js类库的网站,该网站里的库都是压缩后不大于5KB的,非常实用,该网站的资源都托管到了github。plainjs 该仓库都是用原生js写的插件和组件,非常实用,该网站的资源都托管到了github。

本文主要把这项目项目归为一下几类依次展开:

  • 综合/资源
  • 面试相关
  • 样式/UI/css
  • 构建工具/预编译
  • 测试/工具
  • canvas/数据可视化
  • 动画
  • 插件框架、库和组件
  • 移动端
  • Node.js相关
  • 模板引擎
  • WEB编辑器
  • React相关
  • 编程软实力
  • 浏览器兼容方案
综合/资源

frontend-dev-bookmarks 一个巨大的前端开发资源清单  star: 24705Awsome-Front-End-learning-resource github最全的前端资源汇总仓库  star: 4158mobile-web-favorites 移动端H5开发经验、资源、以及踩坑汇总  star: 1307Front-end-tutorial 最全的资源教程-前端涉及的所有知识体系  star: 3667awesome-javascript 一系列很棒的javascript库、插件、资源  star: 15222front-end-collect 作者分享自己长期关注的前端开发相关的优秀网站、博客、以及活跃开发者  star: 3877javascript airbnb出品写js最佳的姿势,已成众多公司js代码风格的标准  star: 75330Mars 腾讯移动web前端知识库  star: 7278awesome-wechat-weapp 小程序开发资源汇总,应有尽有  star: 17357gold-miner 掘金翻译计划,可能是世界最大最好的英译中技术社区,最懂读者和译者的翻译平台  star: 15949 viewBlog 前端大牛的博文,优质文章  star: 7146Best-App 收集&推荐优秀的 Apps/硬件/技巧/周边等(与前端无关)  star: 11578

面试部分

FE-interview 收集的前端面试题和答案  star: 3722resources 知名互联网企业内推,需要换工作的小伙伴擦亮眼睛了  star: 1644CS-Interview-Knowledge-Map 一份前端面试资源,作者很用心,还配有专门的网页  star: 10690 viewnode-interview 如何进入饿了么前端团队,node面试题集合  star: 7274 view

样式/UI/css

materialize materialize 是material design一套轻量级的纯CSS框架。material design 是Goole提出的一套UI设计方案,并应Goole用于所有产品中 star: 33784 viewSemantic-UI 让你使用任何html标签 来表现ui控件,这是一款语义化设计的前端框架,为攻城师而制作的可复用的开源前端框架  star: 42654

uikit 一个轻量级的、模块化前端框架,它被用于快速开发强大的web界面。也是一款优秀的响应式html5框架 star: 13018primer github站点所使用的一套css框架  star: 7567weui 为微信web服务量身设计的一套ui框架  star: 19880pure 一组很小的,响应式的css组件,你可以在网页的项目上到处使用  star: 18978normalize.css 一个可定制的css文件,使浏览器呈现的所有元素,更一致和符合现代标准。支持IE8+ star: 32195iCSS 一系列css有趣的话题,有开发中常用css代码gists  star: 3807css-doodle 一个用css绘制图形的web组件。非常酷!请看demo作品 star: 1201 view

构建工具/预编译

parcel 一个零配置的新一代前端构建工具,识别各种常用类型文件,最优加载模块,代码拆包等,非常值得尝试的一款打包工具 recommand star: 26158webpack 一个模块打包工具,你可以使用webpack管理你的模块依赖,并编绎输出模块们所需的静态文件 recommand star: 43589gulp 基于node.js流构建系统,只有原生几个api,和庞大的插件生态,使用非常简单  star: 30196yo 基于node的一个强健的项目脚手架工具,可以非常方便的构建一个初始项目,有各种类型的项目的脚手架  star: 2598 viewTypeScript 有类型的js预编译语言,非常强大的预编译与代码报错提示,赋予了JS构建大型项目的可能 recommand star: 38380 viewbabel 是一款为了写下一代js的编译器,无需等待浏览器支持就可以使用各种ES6,ES7新的语法 recommand star: 29302stylus 富有表现力的,健壮的css预编译语言, 除了代码简洁,可读性强外,函数功能非常强大,可与js混合使用,实现动态css编程 recommand star: 9404less.js 轻量级的,动态CSS预编语言,具有CSS所有特性,并提供了动态编程方式编写CSS代码。也是各大UI框架所选用的样式语言,比如bootstrap,ant design等 star: 15698node-sass 动态CSS预编语言, 并有拥有强大sass compass的生态圈,可以直接引入并使用,sass是由ruby编写的,node-sass是node重构版本,方便npm直接使用  star: 5445postcss 用js插件来对css样式文件,进行转换、预编译等操作,并且实现了模块化,支持非常多插架 recommand star: 19215

测试/工具

mocha 一个简单、灵活有趣的 javascript 测试框架,用于 nodejs 和浏览器上的 js 应用测试  star: 16125casperjs 一个基于 phantomjs 的开源导航脚本和测试工具  star: 7242karma 自动化完成单元测试,允许你在多个浏览器里执行js代码。让你的 tdd 变得简单,快速,有趣 star: 10128jasmine 是一个简易的 js 单元测试框架, 用来测试 javascript 代码  star: 13800chai 一个针对 nodejs 和浏览器的 tdd (测试驱动开发)/ bdd(行为驱动开发)的断言框架,可与任何 javascript 测试框架集成 recommand star: 5664csscss css代码冗余分析工具,用于分析css存在的冗余  star: 2938async 一个工具模块,提供了直接而强大的 javascript 异步功能。虽然是为 nodejs 设计的,但是它也可以直接在浏览器中使用 star: 24543HTMLHint html 静态代码分析工具,可以集成到代码编辑器或编译系统中  star: 1955eslint js 静态代码分析工具,可以帮你检测 js 语法错误和潜在的问题,可以集成到代码编辑器或编译系统中 recommand star: 12222stylelint 分析和优化你的css样式表的工具,支持多种类型的css文件 recommand star: 5318stylint 由于 stylus 官方团队并没有实现 .styl 文件检查工具,第三方实现了sytlus文件的代码风格检查工具  star: 296headroom.js 是强大的基准测试库,几乎适用于所有js平台。支持high-resolution定时器,并返回重要的统计结果 star: 9905Vorlonjs 远程调试移动端页面的工具,有和PC页面调试一致的体验。比如native app内嵌h5页面、手机h5页面等。国内也一个相同功能的软件moblie debug。star: 2666 view

canvas/数据可视化

d3 一个基于数据操作文档的js数据可视化框架,最流行的数据可视化库之一  star: 78354incubator-echarts 基于canvas的纯js图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表  star: 29730Chart.js 使用canvas标签的简易html5图表  star: 39063c3 一个基于 d3.js 的可重用 javascript 图表库,几乎零学习曲线  star: 7921g2 是一套基于可视化编码的图形语法,以数据驱动,具有高度的易用性和扩展性,可定制的颗粒度极细,相比项目echart大而全且易用的图表库,这个库会让你有不一样的体验,且官方提供了g2-react的react封装包  star: 5838sketch.js 跨平台javascript创意编码框架,gzip压缩后仅有2kb  star: 3211zrender 一个轻量级的canvas类库,mvc封装,数据驱动,提供类dom事件模型,让canvas绘图大有不同  star: 3098highcharts 基于svg的javascript图表框架  star: 7900g6 是一个由纯 JavaScript 编写的关系图基础技术框架。开发者能基于 G6 进行关系图的分析视图和编辑视图进行快速的二次开发 star: 2795

动画
插件

animate.css 一个跨浏览器的css动画库,实现了多种css3动画效果,简单易用易上手  star: 53850anime 极小的js动画引擎,支持 css3、svg 的动画效果,能编写出各种复杂动画效果,gzip后6K左右  star: 23042move.js 极小的js库,支持css3的动画效果,非常简单优雅  star: 4370
TweenJS 是一个简单但强大的js动画库,createjs 套件的一部分  star: 2760bounce.js 一个用于制作漂亮的css3关键帧动画的js库,使用其特有的方式生成的动画效果  star: 5650tween.js 一款可生成平滑动画效果的js动画库,允许你以平滑的方式修改元素的属性值,它可以通过设置生成各种类似css3的动画效果  star: 5764parallax 轻量级的的视差引擎,能对智能设备的方向作出反应  star: 13271velocity 是一款和jQuery的 $.animate() 有相同API的动画引擎,很适合移动端的动画开发,还打包了颜色动画,转换,循环,easing效果,类动画、滚动等功能  star: 15056

front-end-plugins 前端常用插件汇总  star: 755awesome-browser-extensions-for-github 收集关于github上优秀的浏览器插件,非常实用  star: 1292video.js 开源的html5和flash视频播放器,支持自定义进度条、按钮以及工具栏的底色  star: 22351fullPage.js pc端的全屏滚动插件  star: 24488onepage-scroll 可以轻松建立一个动感的响应式的滚动效果页面,比较适用于单页面的专题站。支持现代浏览器和IE8以上版本 star: 9347superslides 致力于解决网站大部分特效展示问题,网站上常用的焦点图/幻灯片,tab标签切换,图片滚动,无缝滚动等  star: 1478github-hovercard github 鼠标悬停显示用户,仓库等摘要信息  star: 1164

ice 阿里飞冰,从此再也不担心管理系统的开发。(个人觉得简单项目还是可以,复杂的做不了) star: 7339 viewpolymer 以一切皆组件、最少化代码量、最少框架限制为设计理念的web组件构建框架  star: 20117impress.js 创建令人兴奋的演示。使用css3的转换和过渡,这个库允许你创建令人印象深刻的演示文稿 star: 33881ScrollMagic 一款非常赞的滚动交互的js插件,可用于官网与宣传广告场景  star: 10037 viewreveal.js 基于css3的3D幻灯片工具,能够制作绚丽的演示文稿并生成html格式,将它发布到web上  star: 42092nodePPT 使用nodejs写的网络幻灯片,可能是迄今为止最好的网页版ppt  star: 5068three.js 是js编写的webgl第三方库,提供了非常多的3D显示功能  star: 44417TimelineJS 轻松制作时间轴  star: 8577highlight.js js语法高亮,既可以运行在浏览器端也可以运行在服务端  star: 12783commander.js nodejs命令行工具,可用于制作那种node命令行终端应用  star: 12342togetherjs 由Mozilla打造的一款可以给网站添加实时协作功能的js库  star: 6174HTML 轻量级的简化与dom操作的js库  star: 1438wechat.js 微信相关的 js 操作:分享、网络、菜单 star: 917JavaScript-Load-Image 一个js加载和转换图像文件的库  star: 3048progress.js 一个js的库,帮助开发人员为网页上的每个对象创建和管理进度条效果  star: 2323foundation 号称世界上最先进的响应式前端框架,也是一款移动端优先的框架  star: 27575Sugar 扩展了现有的js对象的方法,让你可以用更少的代码做更多的事情  star: 3938todomvc 帮你挑选一款mv框架,它使用不同的最流行的mv框架实现了一个相同的todo应用  star: 24270Pikaday 是一个js日期选择器,特点是轻量级、无依赖和模块化的css  star: 6238webuploader 一个简单的以html5为主,flash为辅的现代文件上传组件。支持大文件分片并发上传,极大的提高了文件上传效率 star: 6115headroom.js 是一个轻量级、纯js组件,用来隐藏或展现页面上的元素,为你的页面留下更多展示内容的空间  star: 9905ua-device 史上最全面的userAgent解析库,百度FEX出品  star: 829share.js 一键分享到微博、QQ空间、QQ好友、微信、腾讯微博、豆瓣等  star: 2240

框架、库和组件
移动端

fastclick 触摸UI上的消除点击延迟js库  star: 16750mui 最接近原生APP体验的高性能框架  star: 4033SUI-Mobile 由阿里巴巴国际UED前端出品的移动端UI库,轻量精美  star: 5740amazeui 移动优先的跨屏前端框架。面向html5开发,使用css3做动画和交互  star: 12196ionic 先进的html5移动端开发框架,帮助开发者使用HTML5, css和js做出不可思议的hybrid app  star: 35177zepto.fullpage 专注于移动端的全屏滚动插件  star: 1993lib-flexible 淘宝出品的移动端可伸缩布局方案  star: 8184swipe 加速移动触摸滑块与硬件之间的转换  star: 6724hammer.js 一个支持多点触摸的手势库  star: 18889zepto 一款面向移动端设备、api与jquery兼容的基础库  star: 13987Swiper 纯js打造的滑动特效插件,面向手机、平板电脑等移动终端。能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果 star: 17392

Node.js相关

awesome-nodejs 关于node包和资源的收集  star: 25729node-lessons nodejs包教不包会  star: 13468node123 node.js中文资料导航  star: 2936meteor 快速构建web应用的全栈框架,拥有非常常强大的生态圈,但是国内不是很流行  star: 40213Ghost nodejs开发最新博客系统, 简单简洁, 响应式设计, 支持完全自定义, 免费, 专注博客  star: 27230NodeBB 基于node编写的现代化社区论坛  star: 9118hexo 一款快捷,简单,强大的博客框架  star: 23362nodeclub 使用nodejs和mongodb开发的社区系统  star: 7699N-chat 使用express和socket搭建的多人聊天室  star: 1001electron 使用js,css,html构建跨平台的桌面应用  star: 63960hackathon-starter 一个非常棒的noder初始项目,拥有完整系统架构与用户系统(第三方登录)  star: 24457nest 完全使用typescript编写的服务端框架,相比传统nodejs项目,可维护性、健壮性、可重构性大大加强。号称node版的spring boot star: 8147 view

模板引擎

monaco-editor 微软开发的vs code编辑器的核心编辑组件,可以在浏览器中使用使用的代码编辑器,并支持各种语言高亮,功能相当齐全,制作代码编辑器首选  star: 10899 viewCodeMirror 一个轻量级的代码编辑器,核心代码相当的少,同样支持非常多的编程语言的编辑。star: 15450 vieweditor 下一代的高度定制化的浏览器网页内容编辑器,是基于react开发  star: 6990 viewtinymce 支持图片在线处理,插件多,文档良好且齐全,功能强,编辑能力优秀,界面好看,推荐使用 recommand star: 5642 viewckeditor-dev 界面极其优秀的一款,功能强大,编辑能力极强,基本和word差不多  star: 4162 viewwangEditor 轻量简洁,最重要的是开源且中文文档齐全。设计的UI漂亮 star: 5567 viewsimditor 团队协作工具Tower使用的富文本编辑器,样式好看,插件不多,基本满足需求,维护较好  star: 3972 viewueditor 中文文档,插件多,基本满足各种需求,类似贴吧中的回复界面。缺点:不再维护,文档极少,使用并不普遍,图片只能上传到本地服务器,如果需要上传到其他服务器需要改动源码,较为难办,加载速度慢 star: 3847 viewkindeditor 界面类似百度,效果很像,文档齐全但用例较少,使用还算方便。缺点:总感觉样子不是很好看,没有现代那种风格,还是老式的传统图标  star: 1287 viewdillinger 一个完整的基于node与angular的可以直接部署md项目,可以学习整个项目架构  star: 6067 viewsimplemde-markdown-editor 极简版的markdown编辑器,非常轻量级,可以用于简单的md编辑场景  star: 5515 viewtui.editor 一款功能非常强大的markdown编辑器,有点想”有道云笔记”的md编辑器。非常方便添加自定义功能。recommand star: 7068 view

pug 基于nodejs的强壮的、优雅的功能强大的模版引擎,相当简洁  star: 17150handlebars.js 一个js语义模板库,能让你轻松高效的编写语义化模板  star: 13673artTemplate 性能卓越的js模板引擎  star: 7287ejs tj大神写的嵌入javascript的模板引擎  star: 3985

WEB编辑器
React相关

react-developer-roadmap react的学习路线图2018版  star: 8779react-in-patterns react开发设计模式  star: 9903react-bits react最佳实践,有你想知道  star: 9323awesome-react react资源大全,react该有的都有了  star: 27383create-react-app facebook官方提供react开发命令工具,解决初学者的各种烦恼  star: 54549next.js react服务端渲染框架  star: 28519 viewant-design 管理系统UI组件库,各类组件一应俱全,优秀的文档,良好的api,值得拥有 recommand star: 32790 viewant-design-mobile react移动组件库,兼容react-native recommand star: 5788 viewant-design-pro 阿里团队官方实现的应用antd的,管理系统项目模版,开箱即用 recommand star: 11731 viewgatsby 静态页面生成器,非常强大,自定能力强,模版极多  star: 25050preact react的瘦身版,兼容官方react所有api,压缩后只有3kb  star: 19912recharts d3图表库的react版  star: 9706 viewSortable react的拖拽排序组件  star: 14180 viewreact-loadable react组件懒加载组件  star: 9932react-dnd react拖拽组件,满足各种拖拽需求  star: 9218 viewreact-grid-layout 可拖拽的伸缩的布局组件,admin dashboard必备精选,很高大上 recommand star: 6950 viewdocz 基于react开发的写文档的神器,号称 写文档从未如此简单 recommand star: 9670 viewreact-spring 写react动画的好帮手,不废话看样例  star: 7074 viewreact-360 react VR 开发框架  star: 6364 viewtaro 一套遵循 React 语法规范的 多端开发 解决方案, 有一套代码多端编译,适用小程序与原生app  star: 7296 viewink 用react开发命令行交互工具,很酷  star: 6252ag-grid 非常强大的table组件,完全满足以数据为主的数据展示表格  star: 4231

编程软实力

fks 前端技能汇总,包含前端知识架构,后端知识,运维知识,书籍推荐等  star: 13015javascript-algorithms 包含了多种基于js的算法与数据结构,每种算法都有自己的README说明与YouTube视频  star: 35654 viewCS-Notes 计算机相关的各种记录,涉及到编程的方方面面  star: 33697math-as-code 学术论文可能会吓着自学游戏和图形的程序猿,通过对比数学符号和JavaScript代码来帮助开发者更容易了解数学符号  star: 6306 viewfree-programming-books-zh_CN 免费的计算机编程类中文书籍,不得不说,现在这个时代太好了。star: 37842

浏览器兼容方案

es6-shim 提供兼容性垫片,使ES6能兼容于传统的js引擎  star: 2646Modernizr 用来检测浏览器功能支持情况的js库,可以检测18项css3功能以及40多项关于h5的功能  star: 22910html5shiv 主要解决html5提出的新的元素不被ie6-9识别  star: 9085本文给出了很多优秀的前端开源项目,但是没有具体给出项目地址,不过这个也没事。我以最后一个项目为例,直接打开github链接,按下图搜索,然后对比一下star,差不多的就是原项目了!地址:https://github.com/search?q=html5shiv

全!大厂近两年面试题汇总

大厂面经,堪称红宝书,汇聚了近两年字节,虎牙,YY等大厂的前端面试,都是过来人的经验之谈,文章很长,比较全面,收藏再看。

字节跳动

1 面

  • 对 tree-shaking 的了解
    • 虽然生产模式下默认开启,但是由于经过 babel 编译全部模块被封装成 IIFE
    • IIFE 存在副作用无法被 tree-shaking 掉
    • 需要配置 { module: false }sideEffects: false
    • rollup 和 webpack 的 shaking 程度不同,以一个 Class 为例子
  • Common.js 和 es6 module 区别
    • commonJs 是被加载的时候运行,esModule 是编译的时候运行
    • commonJs 输出的是值的浅拷贝,esModule 输出值的引用
    • webpack 中的 webpack_require 对他们处理方式不同
    • webpack 的按需加载实现
  • 你写的脚手架其中有一个模板是针对销售快速迭代的情节,能介绍一下吗
    • 介绍项目背景:页面多,迭代快,管理混乱,并且 webpack 配置不一样
    • 使用只需要在 page 里面新建文件,然后放入 main 和一些配置文件,输入命令:npm run page=[文件夹名称] env=[环境] method=[dev|build]
    • 介绍一下 node 如何实现,和 webpack 配置合并策略
  • 图片编辑器做的性能优化
    • 图片变化通过矩阵变化,移除 html2Canva
    • 抽离 Matrix.js 里面的三元一次方程求解公式来取代传统的克拉默法则
    • 自定义栈,通过可逆矩阵,亮度,饱和度,色差的逆公式,做出返回效果,而不是每次结果用 base64 保存,消除内存消耗
    • webwork 的尝试和数据测试,证明在计算量不大情况下反而更慢
    • window.performance.mark 埋点,和 1px 的 gif 上传关键步骤时间优化
  • 能介绍一下缓存策略吗
    • 强缓存 cache-control、express
    • 协商缓存 304、ETag、modify
  • 301、302、307、308的区别

OK,搞完上面问题,开始做题:

  • 1. 两数之和:5 分钟内就做完

技术征文图

  • 洗牌算法:5分钟内写完

做完上面 2 道题后:

面试官:emm….面试时间还没结束再做一道题目吧!

  • 215. 数组中的第K个最大元素

技术征文图

  • 花了点个大顶堆,然后很快就求出来
  • 面试官:emm。。。。还有点时间,你还有想到别的办法吗
  • 又写了个快排解法,写完之后面试官说顺便写个归并排序,我就改了一下写出来

好了,面试结束,然而这才是噩梦的开始。由于算法题做的太快,不知面试官写了我啥评价,后面的面试基本变成做各种题。

2 面

  • 图片编辑器做的性能优化(以上)
  • redux-saga 和 mobx 的比较
    • saga 还是遵循 mvc 模型,mobx 是接近 mvvm 模型
    • 介绍项目为何要使用 mobx 更合适
    • 由于是直播相关的 electron 项目,存在音视频流,和一些底层 OS 操作,那么我们是否可以以麦克风视图开关对于音频流的处理为例子,把 OS 的一些操作与数据做一个映射层,就像数据和视图存在映射关系一样,那么数据的流动就是 view -> 触发action -> 数据改变 -> 改变视图 -> 进行 os 操作
    • 然后说了一下 mobx 大概实现的原理,如数据劫持,发布订阅。
  • https 有了解吗
    • 简单讲了一下非对称加密的握手过程
    • 证书签名过程和如何防止被串改
  • 跨域有了解过吗
    • webpack-dev-server 原理和如何处理跨域
    • nginx 转发
    • CROS 中的简单请求和非简单请求
    • 非简单请求下发起的 options
  • localstorage、sessionStorage 和 cookie 的区别
  • cookie 跨域时候要如何处理

然后就开始做题:

  • 70. 爬楼梯

技术征文图

(又是 5 分钟写完)

  • 面试官:那我们改编一下题目,改成 746. 使用最小花费爬楼梯。

技术征文图

  • 我:修改一下之前的答案,很快做出来。
  • 面试官:还有点时间,我们再做一题稍微难一点的 72. 编辑距离

技术征文图

我:这题居然说稍微难点???还好之前做过,那方法真的不是一般人想得出来。然后又做出来了。

面试结束了,感觉都是在做题。

3 面

  • 自我介绍
  • 介绍项目
  • electron 的主进程,渲染进程之间区别和他们通信手段
    • ipcMain、ipcRenderer
    • localStorage
  • webView 和 Iframe 区别
    • webView 应用和嵌入内容之间的交互全部都是异步的
    • 应用和嵌入内容之间的交互全部都是异步的
  • 你这个 PC 应用做了哪些优化
    • 录屏优化
    • 大型文件上传优化
    • 用 mobx 重写之前的 redux-saga,引入 os 层概念
    • electron-update 失效紧急处理办法
  • 大型文件上传
    • 文件切片
    • 用 web-work 单独线程计算文件的 hash 值
    • 上传由于和其他接口同一域名,所以要做并发数处理
    • 进度条
    • 对于已经传过的文件进行跳过秒传,对于失败做失败重传处理
    • 然后有说了一下感觉还能改进的地方
    • 要发挥 electron 能使用 node 的优势,文件切片,hash 计算和上传都可以用 node 实现,并且开不同的进程处理。由于上传是用 node 模块,不会有浏览器同一域名下 6 个连接的限制。为何没做,因为在写别的更加紧急的东西。。。。
  • 录屏优化
    • 需要对整个屏幕进行录制
    • 对比了 FFmpeg 和 mediaSource 的性能差异,如 CPU 和内存消耗
    • 又对比一下 mediaSource 的各种编码性能差异 vp8、daala、h264、opus 和 mpeg
    • 一开始是把视频流写在一个变量里面,这样会造成很大的性能问题
    • 解决办法是每个 10s 把流用 node 的 file 写在硬盘里面,然后结束录制时候,把每个 10s 的小视频片段用 FFmpeg 合成一个大的文件

开始做题,做了一题比较偏冷的题目,看概念我都要理解几分钟的。

技术征文图

虽然做出来,但是不是用数组实现,而是用链表,面试官问我如何再优化,我就是说改成跳表,空间换时间,但是其实正确答案是二分查找……

4 面

四面就比较轻松,问了一下项目就开始做题。

先从简单开始 112. 路径总和

技术征文图

做完后在此基础上,改变成

  • 路径不需要从根节点开始,也不需要在叶子节点结束

虽然题目不难,我也做了减枝的处理,但是面试官说还能优化,如何减少重复计算。这就难倒我了,我知道需要用一个 map 来保存中间的结果,但是这个 map 的 key 如何设计一时想不出来。想了很久说没思路面试就结束了。

虎牙

1 面

  • http 的 get 和 post 区别
  • 缓存策略
  • https 的握手过程
  • http2 的特点
    • 二进制传输
    • Header 压缩,顺便吹了一下哈夫曼编码
    • 多路复用
    • 服务器推送
  • weak-Set、weak-Map 和 Set、Map 区别
  • mvvm 模型和 mvc 模型区别
  • 如何实现一个 mvvm 模型
    • 数据劫持 + 发布订阅
  • 为何你用 mobx 重构了 saga,说说两者之间的区别
    • 简单说了一下 mobx 的实现原理
  • 说说 vnode 的了解
    • vnode 是作为数据和视图的一种映射关系
    • vue 和 react 的 diff 算法有相同和有不同,相同是都是用同层比较,不同是 vue使用双指针比较,react 是用 key 集合级比较
  • 讲讲 webpack 的性能优化
    • 体积:讲了一下 tree-shaking 了解
    • 打包速度:cache-loader、dll、多线程
  • 有写过 plugin
    • 没有,但是了解他的原理,讲了一下大概有哪些 compiler 钩子
  • 了解 webpack-dev-server 的 HMR 实现原理吗
  • 手写一下防抖和节流

2 面

  • 你做过直播,能介绍一下 webRTC 或者现在使用直播方案吗
    • 虽然我是使用声网的 SDK,但是大概了解过一般直播的直播方案
    • 讲了一下 NAT、STUN、RTP、SDP 的基本概论
    • 然后两个信令服务器,一个是声网用来控制进房间媒体流的 socket,一个是业务逻辑的 socket
  • 编码方面有了解过吗,能解释一下码率吗
  • 对于 P 帧、I 帧、B 帧有了解过
    • I 帧:关键帧。可以单独解码成一幅完整的图像。
    • P 帧:参考帧。解码时依赖于前面已解码的数据
    • B 帧:前后参考帧 B 帧后面的 P 帧要优先于它进行解码,然后才能将 B 帧解码
  • RGB 和 YUV 区别
  • 有了解过哪些直播协议
    • httpflv 传输方式:http 流,格式:flv,连续流
    • rtmp 传输方式:tcp 流,格式:flv,连续流
    • hls 传输方式:http,格式:TS 文件,移动端兼容但 PC 不兼容
    • dash 这个不太常见只知道传送方式是 http
  • flv 和 mp4 区别有了解过吗
    • 他们都是属于容器,区别在于文件头信息
    • flv 是属于流式文件是可以边传边解的,不需要通过索引分包,但是 mp4 是需要依赖索引表
  • MediaSource 规范有了解过
    • 没怎么了解,但是还是扯了一下不同码率视频切换是怎么做的

然后还问了一下别的东西,但是我不是很懂就不知清楚了,感觉这一轮面试好奇怪。前端基本没面,反而音视频处理问了很多。

3 面

  • webSocket 和 ajax 的区别
  • xss、csrf 有了解过吗,如何防范
  • 有了解过 React 的 fiber
    • fiber 诞生的背景,为何 react 有时间切片而 vue 不需要
  • 能简单介绍一下 react 执行过程吗
    • performUnitOfWork
    • beginWork
    • completeUnitOfWork
    1. jsx 经过 babel 转变成 render 函数
    2. create update
    3. enqueueUpdate
    4. scheduleWork 更新 expiration time
    5. requestWork
    6. workLoop大循环
    7. Effect List
    8. commit
  • 能介绍一下 hook 吗
    • 比起 hoc,hook 的复用性高
    • useState、useEffect、useRef 用法
    • 优化 usecallback、useMemo
  • 情景题,做一个直播弹幕
    • 字幕的速度,大小
    • requestAnimationFarme 和 setTimeout 区别
    • 弹幕节流问题
    • socket 和轮询优缺点,弹幕池的设计
    • 如何避免弹幕碰撞(这个我答得不好,后来搜索一下有一个飞机场算法)

4 面

这一面就是聊人生,扯得比较远。讲了一下产品一般盈利套路,如何拉新、留存、激活、转换和收益。以前在网易 CC 电竞做的事情。对中国电竞前景的看法。

Bigo

1 面

由于是年前面的,所以在会议室面

  • 自我介绍
  • 介绍项目
  • 你项目用到线形代数,我来考考你记不记得可逆矩阵的逆矩阵求法。
    • 当场白板可逆矩阵的逆矩阵求法
  • 求一下三个三元一次方程
    • 当场白板用克拉默法则求出方程 x,y,z 的解
    • 然后写一下 matrix.js 里面的优化方程(虽然我也不知道他是什么原理)
  • 如何使用尽可能少的空间做矩阵的转置
    • 本质上就是867. 转置矩阵

技术征文图

然后有白板写了一下

  • 能讲讲欧拉角和旋转矩阵吗,还有他们的相互转换
    • 我:???不过之前做项目有 AR 集成,调用接口时候用到,所以勉强讲了一点,但是转换公式我就不会写了

做到上面,我就十分懵逼,我是不是面错岗位了。

技术征文图

然后是情景题,当场设计系统。

情景以下:

  • 这是一个多人在线协同网页
  • 主要做的是视频标识系统,用来训练 AR 用的模型
  • 并且同一时间,用一视频帧可以有多个人标识

emm。。。。那我大概知道为何之前问我这么多数学问题

这个项目的难点有以下

  • 视频的时间帧的确定
    • 由于视频中会存在 I 帧、P 帧、B 帧作为干扰,所以一个视频 25 帧的话,但是实际上不是每一秒都是 25 帧的,每秒帧的数目是动态的
    • 但是视频信息又对应地方 DTS 即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据,和 PTS 即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。我们只需要拿到 PTS 就可以了
  • 绘画过程中 canvas 的优化
    • canvas 应该分两层,一层是没有选择的图形,一层是选中的图形,当图形选中时候会提升到编辑区域的 canvas
    • 对于不规则图形,选择判断方法使用射线法思路,带入公式就可以知道图形是否被选择
  • 多人协同问题,他们之间如何互相通知
    • 使用信令服务器,用 websocket 连接
  • 如果两个人以上同时对一个标签做处理,这种冲突如何处理
    • 其实这个在我做在线白板时候会遇到的问题,这种问题可以类比成游戏中的状态同步和帧同步这两种解决办法,就和面试官扯了一下。

面完情景题,就做算法题,题目也是很奇怪的。

  • 第一题:洗牌算法,这个可以
  • 第二题:假设有偶数位的整数,将整数分开两边,然后对每边的每个数组的每一位求总和,当两边的总和相对就认为这组数符合要求,求2n位数的符合要求数占总数的多少。。。。。有点晕
  • 例子:287962 可以分成 287 962,其中 2 + 8 + 7 = 9 + 6 + 2,那么他就是符合要求的。

2 面

可能一面比较难,二面就比较随便:

  • 浏览器缓存策略
  • 跨域处理
  • https 握手
  • http2 特性
  • tcp 三次握手
  • 从 url 到页面显示
  • redux 和 mobx 的差异
  • tree-shaking
  • 项目的性能优化
  • css 的 BEM 规范
  • 当场设计一个 toast
  • LRU 实现
  • DNS 的路径选择用了啥算法

3 面

聊得比较广,没啥重点

YY

1 面

  • mvvm 和 mvc 模型区别
  • mvvm 的实现
  • 了解 fiber 吗
    • 答案之前有
  • 了解 hook 吗
    • 答案之前有
  • 为何 react 点击事件放在 settimeout 会拿不到 event 对象
    • react 的事件合成
  • setState 是异步还是同步
    • 本质上都是同步,只不过改变 state 的时机不同
    • 由一个是是否批量更新变量来决定
    • 放在 setTimeout 就能实时改变
  • 有用过 node 吗,讲讲流
  • koa2 和 express 区别
    • express 是大而全有路由等,koa2 小而精通过中间件
    • koa2 能使用 async await,express 不能
    • koa2 有洋葱模型和 ctx 上下文,express 没有
  • 讲讲洋葱模型
  • 实现一个函数 compose([fn1,fn2,fn3..]) 转成 fn3(fn2(fn1()))
    • 这个本质上就是中间件实现逻辑,之前看了 Koa2 一点源码,还好记得
  • koa2 和 egg 的区别
    • egg 是在 koa2 上的封装
    • egg 有 controller,service,router
    • 约定了文件目录结构
  • 鉴权有了解过了
    • Seesion/cookie
    • Token
    • OAuth
    • SSO
    • 还好项目都涉及过,虽然不是我用node写的,是后端写的,但是那时候好奇问了一下,并且查了一些资料,勉强答出来

2 面

  • 浏览器缓存策略
  • 跨域处理
  • https 握手
  • xss 和 csrf 攻击
  • Typscript 有了解吗,能讲讲吗
    • 接口
    • 枚举
    • 泛型
  • webpack 优化
  • tree-shaking
  • HMR 实现原理
  • nginx 有了解吗
    • 扯了一下跨域如何配置/转发
    • 缓存策略配置
    • 地址重定向配置
  • 场景题,做一个页面下雪
    • 写一个粒子 Class,里面有粒子、大小、图片,每秒移动的距离
    • 一个粒子控制器 Class,包含粒子数量、分布情况,粒子的下落速度
    • 用 requestanimationframe 绘画动画
    • 用 css3 开启硬件 GPU 加速

3 面

三面也是聊得很广,基本木有前端。

学习过程

其实也没有太过特意去准备面试,其实都是靠平时积累的,在 2019 年开始我就制定了自己的学习计划了,并且每天都坚持学习。可参考 lien的每日学习

以下会分为:

  1. 计算机基础
  2. 前端专业知识
  3. 学习心得

顺序有优先度之分,之所以把计算机基础放在第一位,是因为经过这些面试发现计算机基础考察还有比前端还要多,甚至有些公司面试都不怎么问我前端了。

计算机基础

tip:里面涉及很多都是极客时间的课程,然而我并没有打广告。推荐是因为我看完后真心觉得讲的好,当然好是指容易让初学者了解和上手,深度还是去看专门的权威书做普通吧。

数据结构和算法

学习办法不是一开始就刷题,要先学点入门。

  1. 入门方式有很多种看书看视频,边看边敲。
  2. 然后就可以上网看别人面经和一些 leetcode 大神总结的经典题目,按照分类开始刷了。
  3. 每道题至少做 3 次,第一次时候遇到不会就不要想很久,8 分钟没有思路就看答案。因为大家一开始都是没啥思路,只有做多多总结才会慢慢有思路。做完后一周后再做第二次。准备跳槽时候再做第三次。
  4. 算题顺序为算法面试通关 40 讲、剑指 offer、字节跳动专栏、自己总结的高频题。

我刷的题目也不多,就 100 来道,和别人比起就差远了。

技术征文图

但是我做的题目范围比较广,而且都是自己总结高频再去做,命中的几率比较大。

基本数据结构

  • 数组
  • 队列和栈
  • 链表
  • 二叉树
  • hash

常见的算法

  • DFS
  • BFS
  • 滑动窗口(双指针)
  • 回溯
  • 动态规划
  • 贪心(其实动态规划可以解决)
  • 排序
  • 二分查找

参考资料:

  • JavaScript版 数据结构与算法,这个适合新人学习,入门基本。
  • 极客时间- 数据结构与算法之美 在有基础上看这个会更好,里面github有js实现方式,自己动手敲一遍
  • 极客时间- 算法面试通关 40 讲这门课真的是好,里面都是高频经典的题目。
  • leetcode 字节跳动专栏
  • leetcode 剑指 offer

blog:

  • awesome-coding-js用 JavaScript 实现的算法和数据结构
  • labuladong这个动态规范讲得真的好
  • YaxeZhang/Just-Code针对面试训练算法题, 目前包括字节跳动面试题、 LeetCode 和剑指 offer

网络

网络是前端重要中的重要,也是面试高频的范围。很多人都是一开始就去看计算机网络、TCP/IP 协议、这些书入门,也不是说不好,但是对于新手入门门槛可能太高,还没看几页就放弃了。可以一开始看点视频跟着作者一起来抓包,慢慢熟悉。

观看顺序:

  • 极客时间-透视 HTTP 协议HTTP 作为前端最经常接触而且相对独立,可以先学习这个,再学期其他层。
  • 极客时间-趣谈网络协议作者生动用例子解释网络各层的作用和他们之间的关系,在此形成一个整体的架空,方便后面细节的学习
  • 极客时间 – Web 协议详解与抓包实战。这门课从高层到底层,讲解每一层的细节,由于里面讲解很详细也有很多理论知识,如 RSA 算法、基于椭圆曲线的 ECDH 算法等等可以考虑跳过

最后补充的书籍

  • 图解 http 协议
  • 图解 tcp 协议
  • TCP/IP 详解(第一卷)

tips:

对于前端来说,http,http2,https 的握手是高频题,要主要复习。

其他

本来想聊聊计算机组成原理、操作系统和编译原理,但是一个我学得不精,第二面试也没有怎么问,操作系统就问 linux 的一些简单指令和写一下 Jenkins 的脚本而已。或者后端对这方面会问得比较多。

前端专业知识

前端基础-JS

以下必须要十分熟悉:

  • 类型,涉及以下:
    • 类型种类
    • 判断
    • 转换
    • 深度拷贝
  • 闭包,涉及以下:
    • 作用域
    • v8 垃圾回收
    • 变量提升
  • 异步,涉及以下:
    • Promsie 的历史,用法,简单手写 Promsie 实现
    • async await 原理,generator
    • 宏任务与微任务区别
  • 原型链,涉及以下
    • prototype__proto__
    • 继承
    • oop 编程思想
  • 模块化
    • CommonJS 和 ES6 module
    • AMD 与 CMD 区别(比较旧可以忽略)
  • ES6 特性
    • let const
    • 箭头函数
    • Set、Map、WeakSet 和 WeakMap
    • 之前提及的 Promsie,async,Class,Es6 module

参考资料:

先做一份自我检测,一名【合格】前端工程师的自检清单。然后根据自己薄弱点去看相关资料。

书籍:

入门

  • 《JavaScript高级程序(第三版)》
  • 《你不知道的JavaScript(上)》
  • 《JavaScript 忍者秘籍》(一定要买第二版)
  • 《阮一峰 ES6入门》

BLOG:

  • 前端进阶之道
  • 前端面试与进阶指南
  • ConardLi 的 blog
  • 木易杨前端进阶
  • FE-Interview
  • 冴羽的博客

掘金好文章:

  • (1.6w字)浏览器与前端性能灵魂之问,请问你能接得住几个?(上)
  • (建议收藏)原生JS灵魂之问, 请问你能接得住几个?(上)
  • (建议精读)原生JS灵魂之问(中),检验自己是否真的熟悉JavaScript?
  • (2.4w字,建议收藏)?原生JS灵魂之问(下), 冲刺?进阶最后一公里(附个人成长经验分享)
  • 中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)
  • (中篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂
  • (下篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂

付费好东西:

对知识付费其实是好事情,站在巨人的肩膀上看东西才会远。

  • 前端面试之道|比较基础的前端知识,适合新人
  • 前端开发核心知识进阶| 从基础出发,由浅入深,还有关于很多工程方面的文章,十分推荐。

前端基础-浏览器

有以下比较经典的问题:

  • 缓存策略:协商缓存和强缓存
  • 页面的渲染过程
  • 页面性能优化

参考资料:

  • 浏览器工作原理与实践。这个也是个人十分推荐,因为本人看过《webkit技术揭秘》,发现书上很多东西都是讲浏览器一些实现方式,一堆 C++ 十分难受,但是这个专栏却用十分简单生动的方式来讲述浏览器本质,个人收获很多。
  • 《webkit技术揭秘》

前端基础-css

  • css 选择器优先度
  • rem、em、vh、vw 和 px 的关系,以及移动端适配方式
  • 清除浮动
  • 盒子模型
  • flex
  • 层级上下文
  • 各种布局

前端框架-vue

  1. 第一个层次:使用
    • provide / inject
    • pros emit
    listen
    • event bus
    • 自行实现 dispatch 和 broadcast 方法
    • vue 的生命周期
    • vue 全家桶使用,vuex,vue-router
    • data,computer,watcher使用
    • 组件通信
  2. 第二层:原理
    • 如何简单实现一个mvvm模型
    • new vue 时候发生什么,每个生命周期对应的源码做了什么
    • data,watcher,computer的源码实现
    • nextTick 的原理
    • 指令的本质
    • vue 的性能优化
    • Diff 本质
  3. 第三层:组件的实现

参考资料:

  1. 基础使用:
    • jspang的vue教程
    • Vue2.0开发企业级移动端音乐Web App
    • 前端成长必经之路 组件化思维与技巧
  2. 源码:

技术征文图

技术征文图

  • Vue.js源码全方位深入解析做补充。电子书:《Vue.js 源码揭秘》对于router,vuex,slot,keep-alive有详细解释。
  • 尤雨溪教你写vue 高级vue教程 源码分析!!!!这个我特意去fronted master冲了几百元,没想到居然有搬运。
  • 最后看完就做一下题目,看看自己能达到那种水平吧。12道vue高频原理面试题,你能答出几道?
  • 《深入浅出Vue.js》, 这本书真的好,作者每单介绍一个部分的时候,都会由最简单抽象的一个demo,一步一步变成框架实际的样子,最后拿你写的demo和框架实际的对比,分析双方优缺点。
  • 要先看剖析 Vue.js 内部运行机制把手教你如何写一个最小mvvm模式,mvvm是最核心的思想。当你能懂下面的图时候,那么可以进入下一步了
  1. 组件
    • vant
    • View
    • 先看一下别人的写组件的经验 Vue.js 组件精讲。看完之后就开始动手自己模仿别人的组件了。
    • 推荐模仿对象:

前端框架-react

使用:- Class 的生命周期 – Hooc 高阶组件 – Hook 的使用 – react-router 的使用 – Context – redux(包括mobx或saga)

参考资料:

  • jspang的react教程
  • Hooks 重构旅游电商网站火车票
  • React.js 小书先来简单实现一个mvc模型的react吧。

然后 react 最难就是 fiber,fiber 的代码实现十分复杂,这时候无需太过关注代码,只需要知道,fiber 是解决什么问题而诞生,以及相关的概念就好。

推荐按以下顺序阅读文章

  1. 这可能是最通俗的 React Fiber(时间分片) 打开方式这文章如标题,真是最通俗易懂。
  2. Deep In React之浅谈 React Fiber 架构
  3. Fiber 内部: 深入理解 React 的新 reconciliation 算法
  4. 如何以及为什么 React Fiber 使用链表遍历组件树
  5. Lin Clark – A Cartoon Intro to Fiber – React Conf 2017
  6. Inside Fiber: in-depth overview of the new reconciliation algorithm in React
  7. In-depth explanation of state and props update in React
  8. The how and why on React’s usage of linked list in Fiber to walk the component’s tree
  9. Practical application of reverse-engineering guidelines and principles

以下按自己喜欢挑选吧:

  • react 的事件机制
  1. 【React深入】React事件机制
  2. 谈谈React事件机制和未来(react-events)
  • react 调度机制
  1. 【React深入】setState的执行机制
  2. 再谈react setState-setState如何处理更新?
  • Hook
  1. react hooks的诞生
  2. react hooks进阶与原理
  • yck 系列
  1. 剖析 React 源码:先热个身
  2. 剖析 React 源码:render 流程(一)
  3. 剖析 React 源码:render 流程(二)
  4. 剖析 React 源码:调度原理
  5. 剖析 React 源码:组件更新流程(一)

热身做完,直接上战场吧:

视频:React源码深度解析 高级前端工程师必备技能

电子书:React 源码解析

惭愧,我到现在还没看完。

看得差不多就做点题目吧:

  • 中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂
  • 你要的 React 面试知识点,都在这了

组件设计:

准备看 ant.design的源码

前端工程化-webpack

  1. 使用和基本概念
    • 了解 loader、plugin,并且掌握一些基本常用的
    • 了解 babel

参考资料:玩转webpack

  1. 学会优化
    • 体积优化:tree shaking、按需引入,代码切割
    • 打包速度优化:缓存、多线程打包、优化打包路径

参考资料:

  • 那些花儿,从零构建Vue工程
  • Webpack 4 配置最佳实践
  • webpack4 的30个步骤打造优化到极致的 react 开发环境
  1. 原理
  • webpack构建步骤
  • 细说 webpack 之流程篇
  • Webpack HMR 原理解析
  • 从零实现webpack热更新HMR
  • 干货!撸一个webpack插件(内含tapable详解+webpack流程)
  • 手把手教你撸一个 Webpack Loader
  1. 项目参考

其实 webpack 配置都是靠抄。。。。

  • le-cli
  • fe-workflow这是我参考最多的项目,涉及了初始化项目、打包、测试、联调、质量把控、上线、回滚、线上监控(性能监控、异常监控)等等

学习心得

其实学习心得并没改变,只不过坚持做两年而已

刻意练习

这个之前 2018 年时候写过,就不重复了~

链接:刻意练习

时间管理

对时间敏感

我桌面上有3个表

  1. 倒计时 40 分钟。每次到达 40 分钟后,我必须要去休息,可以结合以前说的番茄工作法。
  2. 秒表。用来检测做题的速度,这就是为何我之前面试算法题基本都是能 5 分钟写出来的原因。还有是统计业务功能需要写多久,方便之后评审排期的时间。

技术征文图

  1. 手机 Ihour 记时。用来记录学习了多少个小时,从量变到质变的过程。

技术征文图

  1. 计划与执行

按以前一样我会有年度计划、月度计划、周计划和日需要执行的任务,并且打卡记录当天所学

技术征文图

  1. 注重饮食

为了确保大脑的清醒和减肥,我采取的是轻食。尽量不吃高 GI 食物,如过度加工过的食物,米饭等等,尽量吃低 GI 食物。GI 其实是血糖指数(glycemic index, GI)的英文缩写,也译作血糖生成指数。主要原理是当人血糖过高或者过低时候,会容易犯困,大脑运转速度变慢。所以要保持血糖的一定稳定,就能减少疲惫感,使效率更高。顺便可以达到减肥效果。


题目只是有助于了解各厂考试方向,但是最终还是要靠自身的实力的随机应变,长缨在手,何惧苍龙! 不断的思考和练习,坚持坚持再坚持,才是王道!

From: 腾讯云, lienjack

初级建站,服务器谁性价比高?

对于从事web开发的小伙伴来说,搞一个服务器建站是不可获取的,得益于云计算的发展,现在阿里云、腾讯云和百度云,都提供了丰富的云产品和人工智能基础服务,而且现在是推广期,各家纷纷撒福利,下面逐一来讲解下他们的产品,大家可以各取所需。

阿里云

阿里云无疑是国内外云计算的绝对老大,市占率遥遥领先,其产品也是刚刚滴,由于种类繁多,这里就不一一列举了,主要有云服务器,虚拟主机,现在都在广撒福利,尤其新用户,优惠不是一般的多,从入门和高性能,个人和企业应用都有合适的产品。推出的阿里云大学里面很多人工智能基础方面的干货,可以进去多学习。

阿里云

腾讯云

腾讯的云业务几乎和阿里云同时起步,但是由于定位模糊以及犹疑,腾讯云错失良机,以至于现在云市场现在仍然落后阿里一大截,不过还好中国市场庞大,即使是老二,也依然是一个庞然大物。而且最近几年开始痛定思痛,奋起直追,各种福利飞起,发展势头很是凶猛,睡蒙的企鹅终于觉醒了,网友们又可以收拾一波小福利了。

腾讯云

百度云

百度云发力晚,但技术出身的百度,凭借其在人工智能上的优势,在云计算的能力不容小觑,大有后发先至的势头。百度虽然一直被唱衰,但是百度网盘却得到一致称赞。现在也是百度云推广的高福利期,有兴趣的朋友可以进去瞅瞅。

百度云

10个AI前端开发工具:提升你的开发效率

十个前端开发AI工具

AI 正在彻底改变软件开发领域,前端开发人员也不例外。以下是10个专门针对前端开发的AI工具,它们将帮助你提高工作效率,优化开发流程。

十个前端开发AI工具

1. Webcrumbs:即时生成组件

Webcrumbs 是一款强大的前端AI助手,能够根据用户请求、图像或屏幕截图即时生成UI组件代码。它支持 TailwindCSS 和常规 CSS,并允许你轻松复制粘贴代码到项目中。此外,Webcrumbs 还提供实时协作、语法突出显示等功能,是一个开源工具。

2. Watsonx Code Assistant:企业级代码生成

由IBM团队开发的 Watsonx Code Assistant 是一款企业级的编码助手,利用生成式AI加快开发速度。它可以根据自然语言请求生成代码,并提供代码建议的来源,提高透明度。此外,它还支持多种产品,如 Red Hat Ansible Lightspeed 和 Z。

3. Coderabbit:团队代码生成和错误检测

Coderabbit 是 GitHub 和 GitLab 上安装最多的AI应用程序,它通过生成AI驱动的上下文反馈来减少代码审查时间。Coderabbit 提供实时聊天评论、带有序列图的拉取请求摘要等功能,帮助团队更高效地协作。

4. v0:React 和 TailwindCSS 智能 UI 合成

v0 是 Vercels 的AI团队创建的一款前端助手,专注于 React、Next.js App Router 和现代 Web 开发实践。它可以将上传的图像转换为 React 代码,并根据 UI 的文本描述生成代码,提供清晰的编码解决方案。

5. Code Llama:代码生成和调试AI

Code Llama 是由 Meta AI 团队构建的一款基于 Llama 2 的AI助手,支持多种流行语言。它通过文本提示生成和讨论代码,特别适用于 Python 开发人员。Code Llama 还提供三种变体,满足不同的需求。

6. CodeParrot:用于 UI 组件的设计到代码AI

CodeParrot 是一个 VS Code 插件,使用 AI 将 Figma 组件或屏幕截图转换为代码。它支持多种编程语言和框架,如 React、Tailwind 和 TypeScript,帮助你快速构建令人惊叹的应用程序 UI。

7. MutableAI:AI 重构和代码优化

MutableAI 的目标是提高生产力 10 倍,帮助开发人员编写代码文档并自动更新 wiki 文章。它还提供 AI 聊天和面向整个团队的非技术模式,快速提取答案。

8. ellipsis.dev:拉取请求审查和代码生成

ellipsis.dev 是一个 AI 助手,可以审查拉取请求、创建发行说明并直接在 GitHub 上修复错误。它支持 20 多种语言,并允许你添加自然语言规则来自定义审查过程。

9. CodeT5+:开源代码生成和理解

CodeT5+ 是基于 T5 架构的代码理解和生成的 AI 助手。它可以生成代码、完成函数块代码,并使用自然语言描述生成函数摘要。CodeT5+ 是一个开源工具,支持多种编码任务。

10. Jam.dev:一键错误报告

Jam.dev 将你的错误报告时间缩短了 20 倍。它是一个浏览器扩展,只需两次点击即可报告错误,并自动包含错误上下文。Jam.dev 还提供 AI 调试助手,帮助开发人员更快地调试和修复代码。

工具再好,也得用起来。当然,如果有更好的工具,我也会持续分享出来。

 

HTML迎来一个新元素::很好用,我正在努力转正

前端发展堪称变异级的发展,五花八门,眼花缭乱,但html元素的变化一般相对稳定,只有在重大版本更新时候才会有新html元素的加入和旧html元素的弃用。最近Chrome 126 于发布了稳定版本,其中一个比较有趣的变化就是给 HTML 带来一个新的元素:<permission> ,它将从这个版本开始试用,并且正在努力走向标准化,也就是这个新成员还在试用期,尚未转正。

但为啥要新加一个元素呢?那肯定有啥绝活呗,下面这篇文章非常详细的介绍了 <permission> 元素的用法,大家可以试试,发表下自己的试用感受。

Web 权限提示的问题

当 Web 应用程序需要访问浏览器的高级功能时,需要向用户主动请求许可。例如,当百度地图使用 Geolocation API 获取用户的地理位置时,浏览器会提示用户申请权限,这是权限规范中定义明确的概念。

new-element-permisson-html

new-element-permisson-html

申请权限的触发方式一般分为两类,被动隐式触发,或者主动显示触发:

例如,Geolocation API 是一个强大的 API,它的使用依赖于首次使用时隐式询问的方法。例如,当程序调用 navigator.geolocation.getCurrentPosition() 方法时,权限提示框会在第一次调用时自动弹出,还有另外一个例子是 navigator.mediaDevices.getUserMedia()

一些其他的 API,如 Notification APIDevice Orientation API,通常有一种显式的方式通过静态方法来请求权限,如 Notification.requestPermission()DeviceMotionEvent.requestPermission()

网站可以在加载时立即调用诸如 navigator.mediaDevices.getUserMedia()Notification.requestPermission() 等方法。这会导致在用户还没与网站进行交互时就弹出权限提示。这就是明显的权限滥用行为,并且影响到两种方式,既包括首次使用时的隐含询问,也包括提前明确请求。

new-element-permisson-html-2


new-element-permisson-html-2

权限滥用导致浏览器厂商要求有像点击按钮或按下按键这样的用户操作,然后才会显示权限提示。这种方法的问题在于,浏览器很难确定某个特定的用户操作是否应该导致显示权限提示。也许用户只是因为页面加载时间太长而在页面上随意某个地方随便点击,有些网站也变得非常擅长诱骗用户点击内容来触发提示。

另一个问题是权限提示框通常显示的方式:在网站的 “死亡线” 之上(特别是在大屏幕上),也就是说,在应用程序能够绘制到的浏览器窗口区域之外。用户在刚刚点击了窗口底部的一个按钮后,可能会错过浏览器窗口顶部的提示,这种情况还是挺常见的。当浏览器有应对权限滥用的缓解措施时,这个问题往往会更加严重。

new-element-permisson-html-2


new-element-permisson-html-2

另外,用户一旦做出了拒绝某个权限的操作,之后想要改变就不太容易了。他们得找到特定的地方,比如那个网站信息下拉菜单,然后去进行重置或调整权限的操作,而且还得重新加载页面才行。网站也没办法提供很方便的途径让用户快速改变权限状态,还得详细地告诉用户怎么去找到地方改变设置。

 new-element-permisson-html-2

如果某个权限是非常重要的,比如视频会议软件要用麦克风权限,那像谷歌会议这类的软件就会弹出很显眼的对话框来告诉用户怎么去把之前阻止的权限给开通。

 new-element-permisson-html

<permission> 元素

为了解决上面的这些问题,<permission> 元素诞生了。这个元素允许开发者以声明方式请求使用权限,如下例所示:

<permission type="camera" />

“type” 属性代表你正在请求的权限列表(如果有多个可以以空格分割)。目前,允许的值是 'camera''microphone' 以及 'camera microphone'。默认情况下,这个元素呈现出来的样子类似于具有最简用户代理样式的按钮。

 new-element-permisson-html-2

对于某些允许附加参数的权限,type-ext 属性接受以空格分隔的键值对,例如 precise:true 地理位置权限。

当用户与 <permission> 元素交互时,他们可以循环经历各个阶段:

如果他们之前不允许某项功能,他们可以在每次访问时允许该功能,或者在当前访问时允许该功能。

图片

如果他们之前允许该功能,他们可以继续允许,或者停止允许。

图片

如果他们之前不允许某项功能,他们可以继续不允许它,或者这次允许它。

图片

<permission> 元素的文本会根据状态自动更新。例如,如果已授予使用某项功能的权限,则文本会更改为表示允许使用该功能。如果需要先授予权限,则文本会更改为邀请用户使用该功能。将之前的屏幕截图与以下屏幕截图进行比较,以查看这两种状态。

图片

<permission> 元素可以与 Permissions API 一起使用。有许多事件可供监听:

  • onpromptdismiss:当元素触发的权限提示被用户关闭(例如,单击关闭按钮或单击提示之外)时,会触发此事件。
  • onpromptaction:当元素触发的权限提示已被用户对提示本身采取某种操作解决时,触发此事件。这并不一定意味着权限状态已经改变,用户可能已经采取了维持现状的操作(例如继续允许权限)。
  • onvalidationstatuschange:当元素从 "valid" 切换到 "invalid" 时触发此事件,例如当元素被其他超文本标记语言内容部分遮挡时,会认为是 "invalid"

我们可以直接在 HTML 代码中内联注册这些事件的事件监听器(<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />),或者在 <permission> 元素上使用 addEventListener()

<permission type="camera" />
<script>
  const permission = document.querySelector('permission');
  permission.addEventListener('promptdismiss', showCameraWarning);

  function showCameraWarning() {
    // Show warning that the app isn't fully usable
    // unless the camera permission is granted.
  }

  const permissionStatus = await navigator.permissions.query({name: "camera"});
  permissionStatus.addEventListener('change', () => {
    // Run the check when the status changes.
    if (permissionStatus.state === "granted") {
      useCamera();
    }
    // Run the initial check.
    if (permissionStatus.state === "granted") {
      useCamera();
    }
  });
</script>


你觉得这个新html元素z

文章来源:

来源:code秘密花园

参考:https://developer.chrome.com/blog/permission-element-origin-trial

jQuery已死?No!JQuery4.0已完成100%,它依旧锋利,或将王者归来

jQuery,曾经的前端王者,几乎无处不在。以前可以说是无jq,不前端。
但随着各大框架风气云涌,jquery逐渐淡出人们的视野,现在开发还用jq,都有被鄙视的风险。
江湖甚至传言,jquery已死。
但jQuery真的成为历史了吗?不是的,jQuery正在偷偷的进化,jQuery 4.0正准备以王者的姿态重归王位。
Github上jQuery 4.0的开发进度显示已100%完成。

jQuery 4.0

jQuery 4.0

 

前几天看还是99%,士别三日,就全部完成了,得加鸡腿。

jq4.0如此快的进度,可能也是为了回答那个一直被追问的问题:jquery 4.0 为什么这么久都没有发布?

这里想说,既然已经100%完成,想必离发布的日子也不远了。

大家保持期待,想象一下曾经锋利的JQ是否依旧,江湖虽变,但宝刀未老依旧锋利。

前端开发又会发生怎么样的变化呢?

JavaScript将新增两个原始数据类型Record 和 Tuple特性、作用和使用用法

JavaScript又有动作了——将推出两个新的数据类型:Record 和 Tuple 。

JavaScript将新增两个原始数据类型Record和Tuple

这俩是啥呢?其实就是一个只读的 Object 和 Array,其实在其它语言中已经有类似的数据类型了,例如 Python 中也有 Tuple(元祖)这一类型,作用也是一个只读的数组(在Python里叫只读的列表),一起来了解一下,这个特性是一个第2阶段提案(即差不多稳了),想要提前体验的,文末也有 polyfill 的使用教程!

两个新的数据类型:Record 和 Tuple的写法

// Records
const myRecord = #{
name: ’01’,
age: 23
}

// Tuple
const myTuple = #[‘1’, ‘2’, ‘3’]

不用仔细看就能发现,其实就是在原先的对象和数组前面加了个 #

特性:

1 可读性——只读,注意是只读

const myRecord = #{
name: ’01’
}

const myTuple = #[‘1’, ‘2’]

myRecord[‘age’] = 23 // error
myTuple.push(‘3’) // error

这两个例子充分验证这两个新增的数据类型是只读的,不可写入。

非唯一性

在平时的开发中,数组与数组、对象与对象 都不适合直接用 === 进行比较判断,因为每个生成的对象在内存中的地址都不一样

const obj1 = { name: ’01’ }
const obj2 = { name: ’01’ }
const objIsSame = obj1 === obj2   // false

const arr1 = [1]
const arr2 = [1]
const arrIsSame = arr1 === arr2   // false

要想真正比较两个数组或对象是否相等(即我们想要的内容都一样),需要遍历递归去一一对比,而现在呢?Record和Tuple能否解决这一问题呢?

const record1 = #{ name: ’01’ }
const record2 = #{ name: ’01’ }
const recordIsSame = record1 === record2   // true

const tuple1 = #[1]
const tuple2 = #[1]
const tupleIsSame = tuple1 === tuple2   // true

可以看到,只要内部内容一致,即使是两个分别生成的Record或Tuple比较一下,也是相等的

可以看到,只要内部内容一致,即使是两个分别生成的Record或Tuple比较一下,也是相等的

普通对象和数组的转换

转换成普通对象和数组

我可以用对象 Record 和 Tuple 将普通的对象和数组转换

const myRecord = Record({ name: ’01’, age: 23 });   // #{ name: ’01’, age: 23 }const myTuple = Tuple([1, 2, 3, 4, 5]);   // #[1, 2, 3, 4, 5]

支持扩展运算符

我们也可以对Record和Tuple使用扩展运算符

const myTuple = #[1, 2, 3];const myRecord = #{ name: '01', age: 23 };const newRecord = #{ ...myRecord, money: 0 } // #{ name: '01', age: 23, money: 0 }const newTuple = #[ ...myTuple, 4, 5];   // #[1, 2, 3, 4, 5]

JSON方法扩展

现在不是有 JSON.parse 和 JSON.stringfy 两个方法嘛,据说草案中还提到一个不错的想法,那就是给 JSON 对象新增一个 parseImmutable 方法,功能应该就是直接将一个 Record字符串或Tuple字符串 解析成对应的Record和Tuple对象

提前体验

如果你想现在体验该功能,可以装一下babel的插件

# babel基本的库
yarn add @babel/cli @babel/core @babel/preset-env -D

# Record和Tuple Babel polyfill
yarn add @babel/plugin-proposal-record-and-tuple @bloomberg/record-tuple-polyfill -D

在目录下创建 .babelrc,内容如下:

{
    “presets”: [“@babel/preset-env”],
    “plugins”: [
        [
          “@babel/plugin-proposal-record-and-tuple”,
          {
            “importPolyfill”: true,
            “syntaxType”: “hash”
          }
        ]
      ]
}

再创建一个 index.js,内容如下:

const tuple1 = #[1,2,3]
const tuple2 = #[1,2,3]

const record1 = #{ name: ’01’ }
const record2 = #{ name: ’02’ }

console.log(tuple1 === tuple2, record1 === record2)

执行一下babel的命令编译一下

./node_modules/.bin/babel index.js –out-file compiled.js

输出得到的 compiled.js 文件内容如下:

“use strict”;

var _recordTuplePolyfill = require(“@bloomberg/record-tuple-polyfill”);

var tuple1 = (0, _recordTuplePolyfill.Tuple)(1, 2, 3);
var tuple2 = (0, _recordTuplePolyfill.Tuple)(1, 2, 3);
var record1 = (0, _recordTuplePolyfill.Record)({
  name: ’01’
});
var record2 = (0, _recordTuplePolyfill.Record)({
  name: ’02’
});
console.log(tuple1 === tuple2, record1 === record2);

最后执行 compiled.js 即可获得结果

node compiled.js
# Result: true false

@babel/plugin-proposal-record-and-tuple 更多用法见 Babel 官方文档

https://babeljs.io/docs/en/babel-plugin-proposal-record-and-tuple#docsNav

新增的两个数据类型的应用场景

了解了那么多的内容,印象最深刻的应该就是 只读 这个特性,那么基于这个特性,Record 和 Tuple 有哪些应用场景呢?

  • 用于保护一些数据,比如函数的返回值、对象内部的静态属性…
  • 既然具有只读的特性,即不可变对象,那应该也可以作为对象的 key 值吧?

怎么样,对JS即将新增的两个数据类型有比较全面的认识了吗?