wclimb的个人博客--分享


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 搜索

2020年7月前端面试总结

发表于 2020-07-28 | 分类于 面试
| 约 10 分钟

写在前面

  感觉很久没有更新博客了,这段时间我也没闲着。整个七月感觉就沉浸在面试的海洋里,让人不敢去回想,因为真的是太累了。大概统计了一下,在这个月内总共面试了28轮,面试的公司有58同城、米可世界、CSDN、自如、京东、Boss直聘、美团、字节跳动、百度等(排名按面试时间排),有的面试流程没结束,拒绝了杭州阿里和滴滴的面试机会,因为时间实在来不及,到最后拿了几个Offer,具体哪些就不说了。
  面试大体就这些,现在说一下上家公司,上东家可以说是我任职最久的一家公司,也是技术成长最快的一段时间,涉及到各个方面,这也是我选择来LOOK的原因,非常感谢LOOK的培养。在LOOK我主要负责小程序的开发(H5和Node也写),2C的业务压力也是挺大的,修改就意味了会直接影响用户的体验,即使是通过了测试这一关我也会自己多自测多模拟不同场景、不同用户操作习惯去测试,尽可能做到上线产品高可用。开发小程序也是很苦恼的,小程序做久了感觉就被套牢了,很多在小程序实践的经验并不能放到H5和PC上,费了很大的功夫解决或者hack的一个问题往往也就局限于微信小程序了,对自己技术的提升往往并不大,很大问题也是开发人员解决不了的,受限于微信,太难了😂 😂

面试题

遇到的面试题还不少,以下面试题是所有面试杂糅在一起的,就不分公司了,部分是有的是有重复的哈。

  1. 虚拟Dom好处
  2. 怎么判断数据类型
  3. vue怎么强制更新视图
  4. for of和for in的区别
  5. let const var
  6. 说一说bfc
  7. rem和em区别
  8. 说一下垃圾回收机制
  9. 输入url发生了什么
  10. vue生命周期
  11. vue2.0和3.0实现区别
  12. 对象和map的区别
  13. 跨域
  14. 有哪些数组方法
  15. 性能优化
  16. 海报图怎么优化
    阅读全文 »

编写一个较为强大的Vue

发表于 2020-05-26 | 分类于 javascript , vue
| 约 1 分钟

编写一个较为强大的Vue,支持虚拟DOM、diff更新以及基本的API,项目地址:https://github.com/wclimb/euv
demo地址:http://www.wclimb.site/euv/

euv

why euv? because:

1
'vue'.split('').sort().join('') // euv

source:

1
'node'.split('').sort().join('') // deno

Quick Start

安装

1
2
3
git clone https://github.com/wclimb/euv.git
cd euv
npm install

运行

1
npm run dev

目前支持功能

  • ✅ 虚拟DOM
  • ✅ Diff更新
  • ✅ {{data}} or {{data + 'test'}} or {{fn(a)}}
  • ✅ v-for // v-for="(item, index) in list" or v-for="(item, index) in 10" or v-for="(item, index) in 'string'"
  • ✅ v-if v-else-if v-else
  • ✅ v-show
  • ✅ v-html
  • ✅ v-model
  • ✅ @click v-on:click 事件(支持绑定其他事件) @click="fn('a',$event)" @click="fn" @click="show = false" @click="function(){console.log(1)}"
  • ✅ methods 方法
  • ✅ computed 计算属性
  • ✅ watch 监听
  • ✅ beforeCreate、created、beforeMount、mounted、beforeUpdate、updated
  • ✅ :class
  • ✅ :style
  • ✅ $nextTick

补充

虚拟dom 不懂的可以看看我之前发的文章(相关代码相比现在有部分改动):http://www.wclimb.site/2020/03/19/simple-virtual-dom/

编写一个webpack

发表于 2020-04-22 | 分类于 javascript , webpack
| 约 12 分钟

实现功能

  1. 支持 esModule
  2. 支持 import() 异步加载文件
  3. 支持 loader

准备工作

我们需要借助 babel 来解析,先 npm init -y

1
npm i @babel/parser @babel/traverse @babel/core @babel/preset-env -D

最终的文件目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|-- dist           // 打包目标文件夹 
| |-- 0.bundle.js
| |-- 1.bundle.js
| |-- result.js
|-- src // 项目测试代码
| |-- entry.js
| |-- messgae.js
| |-- name.js
| |-- a.js
| |-- b.js
|-- index.html // 加载文件打包出的文件
|-- app.js // 启动文件
|-- init.js // 打包项目需要的初始化代码
|-- babel-plugin.js // babel插件
|-- loader.js // loader
|-- package.json

阅读全文 »

Nodejs之进程

发表于 2020-04-15 | 分类于 Node , 进程
| 约 22 分钟

前言

本文大部分借鉴自深入浅出Node.js

本文开始讲一下 Node 的进程,Node 是建立在 V8 引擎之上的,程序基本上是运行在单进程的单线程上的,那么这样就会导致机器的资源没有被合理的利用,CPU 使用率低,所以我们需要多开进程,充分利用多核 CPU 服务器,但是多开进程又会面临进程管理方面的问题。下面我们来具体说说。

单线程?

我们知道 JavaScript 是单线程的,Node 也是?,Node 其实不是,Node 并非真正的单线程架构,Node 自身还有 一定的 I/O 线程存在,这些 I/O 线程由底层 libuv 处理,这部分线程对于 JavaScript 开发者而言是透明的,只在 C++ 扩展开发时才会关注到。JavaScript 代码永远运行在 V8 上,是单线程的。

创建多进程

Node 提供了创建进程的方法,child_process,这里我们使用 fork 方法,它还有其他几个方法这里就不作介绍了
master.js

1
2
3
4
5
const fork = require("child_process").fork
const cpus = require('os').cpus();
for (var i = 0; i < cpus.length; i++) {
fork('./worker.js');
}

可以看到我们获取当前机器的 cpu 数量,然后批量创建子进程,我们新建 worker.js,内容如下

1
2
3
4
5
6
7
8
9
const http = require("http");
process.title = "worker";
console.log(process.pid)
http
.createServer(function(req, res) {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello World\n");
})
.listen(Math.round((1 + Math.random()) * 1000);

启动

1
node master.js

控制台打印的pid

1
2
3
4
5
6
7
35115
35116
35117
35118
35119
35120
...

1
2
3
4
5
6
7
8
9
10
11
            +--------+         
| Master | <------ master.js
+--------+
/ | \
/ | \
/ | \ <----复制
/ | \
v v v
+--------+ +--------+ +---------+
| 工作进程 | | 工作进程 | | 工作进程 | <------ worker.js
+--------+ +--------+ +---------+
阅读全文 »

Nodejs之实现路由和中间件

发表于 2020-04-14 | 分类于 Node , 模版引擎
| 约 9 分钟

前言

今天来实现一个 node 的路由和中间件

铺垫

我们首先起一个服务

1
2
3
4
5
6
7
8
const http = require("http");
const url = require("url");
http
.createServer(function(req, res) {
const pathname = url.parse(req.url).pathname;
res.end(req.method.toLowerCase() + ": " + pathname);
})
.listen(3000);

访问 http://localhost:3000/ 显示 get: /
访问 http://localhost:3000/test 显示 get: /test

最简单的方法就是下面代码判断逻辑,这样做的话太麻烦了,杂糅在一起了,还得进一步判断不同的请求方法,到底是 get 还是 post 还是其他的,重复代码也会增加

1
2
3
4
5
6
7
8
9
10
11
12
switch (pathname) {
case "/":
res.end("root");
break;
case "/test":
res.end("test");
break;
default:
res.writeHead(404);
res.end("404");
break;
}

阅读全文 »

Nodejs之实现一个模版引擎

发表于 2020-04-14 | 分类于 Node , 模版引擎
| 约 6 分钟

前言

最近看完了朴大的 《深入浅出Node.js》 这本书,在里面学到了许多,也推荐大家可以去看一下,看完感觉可以写几篇文章记录总结一下,提升一下印象,毕竟学到的东西感觉不记下来过不久就容易忘记,大家也要养成学习记录的习惯,方便以后重温,今天来实现一个 node 的模版引擎,当然这个模版引擎在前端也可以用。

借鉴ejs标签

标签借鉴 ejs,用过的同学肯定知道,例如使用 <%= name %> 这种标签来展示数据,使用 <% if(name){ %> 这种标签来做 js 操作,如 if 判断/ for循环,比如下面

1
2
3
4
5
<% if (name) { %>
<h1><%=name%></h1>
<% } else { %>
<h1>请登陆</h1>
<% } %>

渲染方法

我们先来看个简单的渲染

阅读全文 »

Nodejs之实现代理

发表于 2020-04-04 | 分类于 Node , 代理
| 约 6 分钟

前言

我们上线一个网站,往往需要代理来完成需求,不然的话就只能使用 IP 加端口的方式来访问应用,目前基本上都会使用 Nginx 来完成反向代理,那么我们开发 Node 应用一定需要 Nginx 吗?肯定不是,我们完全可以通过 Node 来做,但是大多是不建议你用 Node 去处理,因为 Nginx 功能更强大,比如负载均衡,本文主要是帮你了解如何通过 Node 实现代理

使用http-proxy

最简单的做法是拿已经写好的包直接使用

1
$ cnpm i http-proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const proxy = require("http-proxy").createProxyServer({});

server = require("http").createServer(function(req, res) {
const host = req.headers.host;
switch (host) {
case "your domain":
proxy.web(req, res, { target: "http://localhost:8000" });
break;
default:
res.writeHead(200, {
"Content-Type": "text/plain"
});
res.end("Welcome to my server!");
}
});

console.log("listening on port 80");

server.listen(80);

上面👆代码监听 80 端口(如果你的服务器目前使用来 Nginx,暂用80 端口的话,需要先暂停 Nginx 服务),然后我们通过访问域名(前提是域名做好了解析),然后使用 proxy.web方法反向代理到当前服务下的 8000 端口,到此一个简单的服务完成了

阅读全文 »

Vue源码之nextTick

发表于 2020-03-25 | 分类于 javascript , vue
| 约 4 分钟

前言

今天我们开始讲一下 Vue 的 nextTick 方法的实现,无论是源码还是开发的过程中,经常需要使用到 nextTick,Vue 在更新 DOM 时是异步执行的,只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环 “tick” 中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。

阅读全文 »

撸一个简易Virtual DOM

发表于 2020-03-19 | 分类于 javascript , vue
| 约 8 分钟

前言

上一篇我们讲了一下 Vue 的 虚拟DOM,从创建到更新整个流程。今天带大家撸一个简易的虚拟DOM,本文的大部分借鉴 Vue 源码

浏览器渲染流程

摘自浏览器工作原理与实践

  1. 渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。
  2. 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。
  3. 创建布局树,并计算元素的布局信息。
  4. 对布局树进行分层,并生成分层树。
  5. 为每个图层生成绘制列表,并将其提交到合成线程。
  6. 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
  7. 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
  8. 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

准备

首先我们要明白什么是虚拟DOM,为什么要用到它,虚拟DOM 是使用 javascript 对象来描述 DOM 树,一切的更新修改都是在更改这个对象,然后反应到真实的 DOM 下。要说为什么要用到它,肯定是因为性能好,因为直接操作 DOM 的代价是很大的,比如,一次操作中有 10 次更新 DOM 的动作,虚拟DOM 不会立即操作 DOM,而是将这 10 次更新的 diff 内容保存到本地一个 js 对象中,最终将这个 js 对象一次性 反应到 DOM 树上,再进行后续操作,避免大量无谓的计算。也有人反驳说,使用 虚拟DOM 比起操作真实 DOM 要慢,的确如此,使用 虚拟DOM 确实没有原生操作快,但是既然使用了框架,优化框架都会帮你做,你不用自己去手动做DOM的优化,不用处处去考虑操作 DOM 带来的性能问题,使用 虚拟DOM 可以让性能得到有力的保证。

可以参考知乎问题 网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么?

实现

使用js对象模拟DOM树

这里我们不使用 Vue 的那种根据 template 生成 虚拟DOM 的方法,那样太复杂了,这里只讲简单的方法,我们直接使用 js 对象来描述 DOM

比如如下 的html 代码

1
2
3
4
5
6
7
8
<div id="app">
<h1 data-title="header">Virtual Dom</h1>
<ul class="ul1">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>

阅读全文 »

Vue源码之虚拟DOM

发表于 2020-03-17 | 分类于 javascript , vue
| 约 20 分钟

前言

上一篇我们讲了一下 Vue 的双向数据绑定原理,今天我们开始讲一下 Vue 的 虚拟DOM。
本文会先分析一下 Vue 的 虚拟DOM,然后下一篇文章会带大家撸一个简易的 虚拟DOM

Vue虚拟DOM

创建虚拟DOM

https://github.com/wclimb/vue/blob/dev/src/core/vdom/vnode.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
export default class VNode {
tag: string | void;
data: VNodeData | void;
children: ?Array<VNode>;
text: string | void;
elm: Node | void;
ns: string | void;
context: Component | void; // rendered in this component's scope
functionalContext: Component | void; // only for functional component root nodes
key: string | number | void;
componentOptions: VNodeComponentOptions | void;
componentInstance: Component | void; // component instance
parent: VNode | void; // component placeholder node
raw: boolean; // contains raw HTML? (server only)
isStatic: boolean; // hoisted static node
isRootInsert: boolean; // necessary for enter transition check
isComment: boolean; // empty comment placeholder?
isCloned: boolean; // is a cloned node?
isOnce: boolean; // is a v-once node?

constructor (
tag?: string,
data?: VNodeData,
children?: ?Array<VNode>,
text?: string,
elm?: Node,
context?: Component,
componentOptions?: VNodeComponentOptions
) {
this.tag = tag
this.data = data
this.children = children
this.text = text
this.elm = elm
this.ns = undefined
this.context = context
this.functionalContext = undefined
this.key = data && data.key
this.componentOptions = componentOptions
this.componentInstance = undefined
this.parent = undefined
this.raw = false
this.isStatic = false
this.isRootInsert = true
this.isComment = false
this.isCloned = false
this.isOnce = false
}

// DEPRECATED: alias for componentInstance for backwards compat.
/* istanbul ignore next */
get child (): Component | void {
return this.componentInstance
}
}

以上代码是Vue创建 虚拟DOM 的类,一眼看过去是不是感觉东西太多了?其实我们主要关注主要的几个参数就可以了,tag 、data、children、text、elm、key

  • tag 表示当前 vnode 的标签类型,比如 div ul
  • data 表示当前 vnode 标签上的 attribute,可能是class、id、key
  • children 表示当前 vnode 的子节点
  • text 表示文本内容
  • elm 表示当前 vnode 的真实 DOM 节点
  • key diff算法 需要用到,就是我们开发中写的 :key
阅读全文 »
12…5
wclimb

wclimb

41 日志
19 分类
22 标签
GitHub QQ群 小程序 公众号
Links
  • Lsnsh
  • curtain Tan
  • eraylee
  • flutter体验
  • 技术鹏
  • 苏博客
  • Blog Luo
© 2017 - 2020 wclimb
赣ICP备 17009321号
访问人数 人次