腾讯实习面试总结(二)
什么时候接触前端?对前端的理解?
实验室的项目介绍
为什么选择vue?用过react吗?
vue双向绑定原理
Object.defineProperty(vue2) / Proxy(vue3)
- 为对象的属性来设定getter和setter,从而我们可以劫持用户对对象属性的取值和赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17const obj = {};
let val = 'cjg';
Object.defineProperty(obj, 'name', {
get() {
console.log('劫持了你的取值操作啦');
return val;
},
set(newVal) {
console.log('劫持了你的赋值操作啦');
val = newVal;
}
});
console.log(obj.name);
obj.name = 'cwc';
console.log(obj.name);观察者模式(发布订阅模式)
- 多个订阅者可以向同一发布者订阅一个事件,当事件发生的时候,发布者通知所有订阅该事件的订阅者
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
35class Dep {
constructor() {
this.subs = [];
}
// 增加订阅者
addSub(sub) {
if (this.subs.indexOf(sub) < 0) {
this.subs.push(sub);
}
}
// 通知订阅者
notify() {
this.subs.forEach((sub) => {
sub.update();
})
}
}
const dep = new Dep();
const sub = {
update() {
console.log('sub1 update')
}
}
const sub1 = {
update() {
console.log('sub2 update');
}
}
dep.addSub(sub);
dep.addSub(sub1);
dep.notify(); // 通知订阅者事件发生,触发他们的更新函数
Vue官方文档的解释:
当你把一个普通的 JavaScript 对象传给 Vue 实例的
data
选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的
setter
被调用时,会通知watcher
重新计算,从而致使它关联的组件得以更新。
- 通过Object.defineProperty定义data对象属性的get和set方法,对需要监听的数据进行getter和setter进行劫持,当属性被赋值/取值时,Vue.js就可以察觉到并作出相应的处理
- 通过订阅发布模式可以为对象的每个属性都创建一个发布者,当有其他订阅者依赖于这个属性时,将订阅者加入到发布者的队列中。利用Object.defineProperty的数据劫持,在属性的setter调用的时候,该属性的发布者通知所有订阅者更新内容。
Observer
: 数据的观察者,让数据对象的读写操作都处于自己的监管之下Watcher
: 数据的订阅者,数据的变化会通知到Watcher,然后由Watcher进行相应的操作,例如更新视图Dep
:数据的发布者, Observer与Watcher的纽带。 有一个subs 数组用来保存和这个依赖有关的 Watcher。当数据变化时,会被Observer观察到,然后由Dep通知到Watcher
iview看过源码吗?自己写过组件吗?
iview使用vue组件的定义
- 组件是可复用的 Vue 实例
- 一个组件的 data 选项必须是一个函数。因此每个实例可以维护一份被返回对象的独立的拷贝,如果不是这样,一个实例上面数据的变化就会影响到其他所有的实例
- 每个组件必须只有一个根元素。可以将模板的内容包裹在一个父元素内,来修复这个问题
vue组件的重要概念
- props:通过props向子组件传递数据
- $emit:自定义事件的系统来监听子组件事件
- 父组件通过v-on监听子组件实例的任意事件
- 子组件可以通过调用内建的$emit()方法触发事件,第一个参数是这一组参数的名称,后面的是参数值
- 自定义事件也可以用于创建支持 v-model的自定义输入组件
- slot:通过插槽分发内容
单文件组件
- 使用Vue.component定义全局组件的缺点:
- 全局定义 强制要求每个 component 中的命名不得重复
- 字符串模板 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的
\
- 不支持 CSS 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
- 没有构建步骤 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用预处理器,如 Pug (formerly Jade) 和 Babel
- 单文件组件:使用扩展名为.vue的文件
- 完整语法高亮
- CommonJS 模块
- 组件作用域的 CSS
- 关注点分离不等于文件分离
- 松散耦合的组件
- 在一个组件里,其模板、逻辑和样式是内部耦合的,并且把他们搭配在一起实际上使得组件更加内聚且更可维护
webstorage和cookie的区别?
webstorage
localStorage:localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
sessionStorage:sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。源生接口可以接受,亦可再次封装来对Object和Array有更好的支持。
使用相同的API
- setItem
- getItem
- removeItem
- clear
作用域不同
不同浏览器无法共享localStorage或sessionStorage中的信息。
相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage的信息。这里需要注意的是,页面及标签页仅指顶级窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的。
cookie
生命期为只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 存放数据大小为4K左右 。有个数限制(各浏览器不同),一般不能超过20个。与服务器端通信:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题。但Cookie需要程序员自己封装,源生的Cookie接口不友好
使用
1
2
3
4
5//创建/修改 expires现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期
document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
//获取
var x = document.cookie;
//删除cookie:只需要设置 expires 参数为以前的时间即可优点:具有极高的扩展性和可用性
- 缺点:
- cookie的长度和数量的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB。否则会被截掉
- 安全性问题。如果cookie被人拦掉了,那个人就可以获取到所有session信息。加密的话也不起什么作用
- 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务端保存一个计数器。若计数器保存在客户端,则起不到什么作用
- 安全
- 通过良好的编程,控制保存在cookie中的session对象的大小
- 通过加密和安全传输技术,减少cookie被破解的可能性
- 只有在cookie中存放不敏感的数据,即使被盗取也不会有很大的损失
- 控制cookie的生命期,使之不会永远有效。这样的话偷盗者很可能拿到的就是一个过期的cookie
相同和区别
特性 | cookie | sessionStorage | localStorage |
---|---|---|---|
数据生命期 | 生成时就会被指定一个maxAge值,这就是cookie的生存周期,在这个周期内cookie有效,默认关闭浏览器失效 | 页面会话期间可用 | 除非数据被清除,否则一直存在 |
存放数据大小 | 4K左右(因为每次http请求都会携带cookie) | 一般5M或更大 | |
与服务器通信 | 由对服务器的请求来传递,每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 数据不是由每个服务器请求传递的,而是只有在请求时使用数据,不参与和服务器的通信 | |
易用性 | cookie需要自己封装setCookie,getCookie | 可以用源生接口,也可再次封装来对Object和Array有更好的支持 | |
共同点 | 都是保存在浏览器端,和服务器端的session机制不同 |
了解ES6的哪些新特性?
ES6的模块化?
promise?
js怎么实现链式调用?
链式调用的根本在于上一个函数的返回值有下一个要调用的方法,依次类推。
比较常见做法是自己写个类来封装数据,然后提供一堆处理这个数据的方法,每个(或大部分)方法都返回 this
(return this),这样就能链式调用了。
js怎么创建对象?
1.工厂模式
工厂模式抽象了创建具体对象的过程,用函数封装封装以特定接口创建对象的细节。
1 | function createPerson(name){ |
解决了创建多个相似对象的问题,但没有解决对象识别的问题(即怎样知道一个对象的类型)
2.构造函数模式
1 | function Person(name){ |
- 构造函数和工厂模式的区别:
- 没有显式地创建对象
- 直接将属性和方法赋给了this对象
- 没有return语句
- 可以用instanceof操作符检测对象类型
- 构造函数的问题:
- 每个方法都要在每个实例上重新创建一遍,不同实例的同名函数是相同的
3.原型模式
- 原型和原型链
构造函数Foo()
构造函数的原型属性Foo.prototype指向了原型对象,在原型对象里有共有的方法,所有构造函数声明的实例(这里是f1,f2)都可以共享这个方法。
原型对象Foo.prototype
Foo.prototype保存着实例共享的方法,有一个指针constructor指回构造函数。
实例
f1和f2是Foo这个对象的两个实例,这两个对象也有属性__proto__,指向构造函数的原型对象,这样子就可以像上面1所说的访问原型对象的所有方法啦。
隐式原型(__proto__)与显式原型(prototype)
- 显式原型的作用:用来实现基于原型的继承与属性的共享
- 隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次查找。
用一个包含所有属性和方法的对象字面量来重写整个原型对象
1
2
3
4
5
6
7
8
9
10function Person(){}
Person.prototype = {
name: 'Nucholas',
age: 29,
sayName: function(){}
}
Object.defineProperty(Persion.prototype, "constuctor", {
enumerable: false, //不可枚举
value: Person
})注意:实例中的__proto__指针仅指向原型,而不指向构造函数。重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系
原型对象的问题
- 引用类型值属性的共享
4.组合使用构造函数模式和原型模式
创建自定义类型最常见的方式,就是组合使用构造函数模式与原型模式。
构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。
5.动态原型模式
1 | function Person(name, age, job){ |
6.寄生构造函数模式
除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一摸一样的。
不能依赖instanceof操作符来确定对象类型。
7.稳妥构造函数模式
和寄生构造函数模式类似。
不同:创建对象的实例方法不引用this;不使用new操作符调用构造函数。
从URL输入到页面显示经历了什么?
- DNS解析
- TCP连接,三次握手
- 发送HTTP请求
- 服务器处理请求,返回HTTP报文
- 浏览器解析并渲染页面
- 处理HTML标记,构建DOM树
- 处理CSS标记,构建Style树
- 结合DOM树和Style树为渲染树
- 根据渲染树布局,计算节点的几何信息
- 绘制到屏幕(回流和重绘)
- 断开连接,四次挥手
上面的步骤可以从哪些地方优化?
1.DNS解析
DNS缓存
DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存
DNS负载均衡(DNS重定向)
DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。
CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。
2.TCP连接
3.HTTP请求
- 减少HTTP请求
- 图片地图:多张图片合并成一张,如果每张图片都有不同的超链接,可通过CSS偏移响应鼠标点击操作,构造不同的URL。
- 合并图片
- 内联图片 data:URL
- 合并js和css
- HTTP缓存
- 有效期非常长的Exprires头
- Max-Age(替代Exprires)
4.服务器处理请求,返回HTTP报文
- 压缩响应
- 请求头Accept-Encoding,响应头Content-Encoding
5.浏览器解析渲染
- 减少重绘和回流,特别是回流
- 样式表放在顶部
- js放在底部
- js非阻塞加载
- 异步动态加载
- onload动态脚本
- defer延迟脚本
TCP有什么了解?为什么是可靠的?
讲一下HTTP的头部
常见的请求报头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。
常用标准请求头部
Accept 设置接受的内容类型
Accept: text/plain
Accept-Charset 设置接受的字符编码
Accept-Charset: utf-8
Accept-Encoding 设置接受的编码格式
Accept-Encoding: gzip, deflate
Accept-Datetime 设置接受的版本时间
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
Accept-Language 设置接受的语言
Accept-Language: en-US
Authorization 设置HTTP身份验证的凭证
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 设置请求响应链上所有的缓存机制必须遵守的指令
Cache-Control: no-cache
Connection 设置当前连接和hop-by-hop协议请求字段列表的控制选项
Connection: keep-alive
Connection: Upgrade
Content-Length 设置请求体的字节长度
Content-Length: 348
Content-MD5 设置基于MD5算法对请求体内容进行Base64二进制编码
Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Type 设置请求体的MIME类型(适用POST和PUT请求)
Content-Type: application/x-www-form-urlencoded
Cookie 设置服务器使用Set-Cookie发送的http cookie
Cookie: $Version=1; Skin=new;
Date 设置消息发送的日期和时间
Date: Tue, 15 Nov 1994 08:12:31 GMT
Expect 标识客户端需要的特殊浏览器行为
Expect: 100-continue
Forwarded 披露客户端通过http代理连接web服务的源信息
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17
From 设置发送请求的用户的email地址
From: user@example.com
Host 设置服务器域名和TCP端口号,如果使用的是服务请求标准端口号,端口号可以省略
Host: en.wikipedia.org:8080
Host: en.wikipedia.org
If-Match 设置客户端的ETag,当时客户端ETag和服务器生成的ETag一致才执行,适用于更新自从上次更新之后没有改变的资源
If-Match: “737060cd8c284d8af7ad3082f209582d
If-Modified-Since 设置更新时间,从更新时间到服务端接受请求这段时间内如果资源没有改变,允许服务端返回304 Not Modified
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
If-None-Match 设置客户端ETag,如果和服务端接受请求生成的ETage相同,允许服务端返回304 Not Modified
If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range 设置客户端ETag,如果和服务端接受请求生成的ETage相同,返回缺失的实体部分;否则返回整个新的实体
If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since 设置更新时间,只有从更新时间到服务端接受请求这段时间内实体没有改变,服务端才会发送响应
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Max-Forwards 限制代理或网关转发消息的次数
Max-Forwards: 10
Origin 标识跨域资源请求(请求服务端设置Access-Control-Allow-Origin响应字段)
Origin:
http://www.example-social-network.com
Pragma 设置特殊实现字段,可能会对请求响应链有多种影响
Pragma: no-cache
Proxy-Authorization 为连接代理授权认证信息
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 请求部分实体,设置请求实体的字节数范围,具体可以参见HTTP/1.1中的Byte serving
Range: bytes=500-999
Referer 设置前一个页面的地址,并且前一个页面中的连接指向当前请求,意思就是如果当前请求是在A页面中发送的,那么referer就是A页面的url地址(轶事:这个单词正确的拼法应该是”referrer”,但是在很多规范中都拼成了”referer”,所以这个单词也就成为标准用法)
Referer:
http://en.wikipedia.org/wiki/Main_Page
TE 设置用户代理期望接受的传输编码格式,和响应头中的Transfer-Encoding字段一样
TE: trailers, deflate
Upgrade 请求服务端升级协议
Upgrade: HTTP/2.0, HTTPS/1.3, IRC/6.9, RTA/x11, websocket
User-Agent 用户代理的字符串值
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0
Via 通知服务器代理请求
Via: 1.0 fred, 1.1 example.com (Apache/1.1)
Warning 实体可能会发生的问题的通用警告
Warning: 199 Miscellaneous warning
常用非标准请求头字段
X-Requested-With 标识Ajax请求,大部分js框架发送请求时都会设置它为XMLHttpRequest
X-Requested-With: XMLHttpRequest
X-Csrf-Token,X-CSRFToken,X-XSRF-TOKEN 防止跨站请求伪造
常用标准响应头部
Access-Control-Allow-Origin 指定哪些站点可以参与跨站资源共享
Access-Control-Allow-Origin: *
Accept-Patch 指定服务器支持的补丁文档格式,适用于http的patch方法
Accept-Patch: text/example;charset=utf-8
Accept-Ranges 服务器通过byte serving支持的部分内容范围类型
Accept-Ranges: bytes
Age 对象在代理缓存中暂存的秒数
Age: 12
Allow 设置特定资源的有效行为,适用方法不被允许的http 405错误
Allow: GET, HEAD
Alt-Svc 服务器使用”Alt-Svc”(Alternative Servicesde的缩写)头标识资源可以通过不同的网络位置或者不同的网络协议获取
Alt-Svc: h2=”http2.example.com:443”; ma=7200
Cache-Control 告诉服务端到客户端所有的缓存机制是否可以缓存这个对象,单位是秒
Cache-Control: max-age=3600
Connection 设置当前连接和hop-by-hop协议请求字段列表的控制选项
Connection: close
Content-Disposition 告诉客户端弹出一个文件下载框,并且可以指定下载文件名
Content-Disposition: attachment; filename=”fname.ext”
Content-Encoding 设置数据使用的编码类型
Content-Encoding: gzip
Content-Language 为封闭内容设置自然语言或者目标用户语言
Content-Language: en
Content-Length 响应体的字节长度
Content-Length: 348
Content-Location 设置返回数据的另一个位置
Content-Location: /index.htm
Content-MD5 设置基于MD5算法对响应体内容进行Base64二进制编码
Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range 标识响应体内容属于完整消息体中的那一部分
Content-Range: bytes 21010-47021/47022
Content-Type 设置响应体的MIME类型
Content-Type: text/html; charset=utf-8
Date 设置消息发送的日期和时间
Date: Tue, 15 Nov 1994 08:12:31 GMT
ETag 特定版本资源的标识符,通常是消息摘要
ETag: “737060cd8c284d8af7ad3082f209582d”
Expires 设置响应体的过期时间
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Last-Modified 设置请求对象最后一次的修改日期
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Link 设置与其他资源的类型关系
Link: </feed>; rel=”alternate”
Location 在重定向中或者创建新资源时使用
Location:
http://www.w3.org/pub/WWW/People.html
P3P 以P3P:CP=”your_compact_policy”的格式设置支持P3P(Platform for Privacy Preferences Project)策略,大部分浏览器没有完全支持P3P策略,许多站点设置假的策略内容欺骗支持P3P策略的浏览器以获取第三方cookie的授权
P3P: CP=”This is not a P3P policy! See
http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657
for more info.”
Pragma 设置特殊实现字段,可能会对请求响应链有多种影响
Pragma: no-cache
Proxy-Authenticate 设置访问代理的请求权限
Proxy-Authenticate: Basic
Public-Key-Pins 设置站点的授权TLS证书
Public-Key-Pins: max-age=2592000; pin-sha256=”E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=”;
Refresh “重定向或者新资源创建时使用,在页面的头部有个扩展可以实现相似的功能,并且大部分浏览器都支持<meta http-equiv="refresh" content="5; url=http://example.com/">
Refresh: 5; url=
http://www.w3.org/pub/WWW/People.html
Retry-After 如果实体暂时不可用,可以设置这个值让客户端重试,可以使用时间段(单位是秒)或者HTTP时间
Example 1: Retry-After: 120
Example 2: Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
Server 服务器名称
Server: Apache/2.4.1 (Unix)
Set-Cookie 设置HTTP Cookie
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Status 设置HTTP响应状态
Status: 200 OK
Strict-Transport-Security 一种HSTS策略通知HTTP客户端缓存HTTPS策略多长时间以及是否应用到子域
Strict-Transport-Security: max-age=16070400; includeSubDomains
Trailer 标识给定的header字段将展示在后续的chunked编码的消息中
Trailer: Max-Forwards
Transfer-Encoding 设置传输实体的编码格式,目前支持的格式: chunked, compress, deflate, gzip, identity
Transfer-Encoding: chunked
Upgrade 请求客户端升级协议
Upgrade: HTTP/2.0, HTTPS/1.3, IRC/6.9, RTA/x11, websocket
Vary 通知下级代理如何匹配未来的请求头已让其决定缓存的响应是否可用而不是重新从源主机请求新的
Example 1: Vary: *
Example 2: Vary: Accept-Language
Via 通知客户端代理,通过其要发送什么响应
Via: 1.0 fred, 1.1 example.com (Apache/1.1)
Warning 实体可能会发生的问题的通用警告
Warning: 199 Miscellaneous warning
WWW-Authenticate 标识访问请求实体的身份验证方案
WWW-Authenticate: Basic
X-Frame-Options 点击劫持保护:
deny frame中不渲染
sameorigin 如果源不匹配不渲染
allow-from 允许指定位置访问
allowall 不标准,允许任意位置访问
X-Frame-Options: deny
常用非标准请求头字段
X-XSS-Protection 过滤跨站脚本
X-XSS-Protection: 1; mode=block
Content-Security-Policy, X-Content-Security-Policy,X-WebKit-CSP 定义内容安全策略
X-WebKit-CSP: default-src ‘self’
POST和GET的区别
- url可见性:
- get,参数url可见
- post,url参数不可见
- 数据传输上:
- get,通过拼接url进行传递参数
- post,通过body体传输参数
- 缓存性:
- get请求是可以缓存的
- post请求不可以缓存
- 后退页面的反应
- get请求页面后退时,不产生影响
- post请求页面后退时,会重新提交请求
- 传输数据的大小
- get一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大)
- post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大。
- 效率
- 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据
- 对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
深拷贝和浅拷贝?如何实现深拷贝?方法有什么缺点?
- 浅拷贝:引用类型的值会跟着变化
- 实现深拷贝:
- 递归
- JSON.stringfy和JSON.parse(存在的问题:无法拷贝到undifined、function、symbol这类数据)
搜索引擎优化?
SEO(Search Engine Optimization):汉译为搜索引擎优化。搜索引擎优化是一种利用搜索引擎的搜索规则来提高目前网站在有关搜索引擎内的自然排名的方式。SEO是指为了从搜索引擎中获得更多的免费流量,从网站结构、内容建设方案、用户互动传播、页面等角度进行合理规划,使网站更适合搜索引擎的索引原则的行为
- 网站结构
- 内容
- 用户体验
- 代码
- 语义化标签
补充:关于SPA和SEO
SPA的优点:
- 前后端分离
- 页面之间的切换非常快
- 一定程度上减少了后端服务器的压力(不用管页面逻辑和渲染)
- 后端程序只需要提供API,完全不用管客户端到底是Web界面还是手机等
SPA的缺点:
- 首屏打开速度很慢,因为用户首次加载需要先下载SPA框架及应用程序的代码,然后再渲染页面。
- 不利于SEO
因为就目前而言,部分搜索引擎如Google、bing等,它们的爬虫虽然已经支持执行JS甚至是通过AJAX获取数据了,但是对于异步数据的支持也还不足。
如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。
SSR
- 更快的响应时间,不用等待所有的JS都下载完成,浏览器便能显示比较完整的页面了。
- 更好的SSR,我们可以将SEO的关键信息直接在后台就渲染成HTML,而保证搜索引擎的爬虫都能爬取到关键数据。
- 同构javascript
什么是语义化?语义化的好处?
根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。
优点:
- 有利于搜索
- 容易兼容不同设备
- 结构清晰,利于团队的开发、维护
HTML5的新特性?
- 语义化标签,添加
<header><header/><nav><nav>
等标签 - 增强型表单,HTML5 拥有多个新的表单 Input 输入类型。这些新特性提供了更好的输入控制和验证。新增表单元素和表单属性
- 多媒体, 用于媒介回放的 video 和 audio 元素
- 图像效果,用于绘画的 canvas 元素,svg元素等
- 地理定位
- 拖放API
- Web Worker。web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。类似于实现多线程。
- 离线 & 存储,对本地离线存储的更好的支持,local Store,Cookies等
- WebSocket。WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。服务器推送技术。
常见web安全和防御?
略
git和svn的区别?各自的应用场景?
1)GIT是分布式的,SVN不是
2)GIT把内容按元数据方式存储,而SVN是按文件
3)GIT分支和SVN的分支不同
4)GIT没有一个全局的版本号,而SVN有
5)GIT的内容完整性要优于SVN
6)Git下载下来后,在本地不必联网就可以看到所有的log,很方便学习,SVN却需要联网
写过微信小程序吗?为什么小程序的性能比较好?
一个WebView只对应一个用户界面。
在打开当前页面后,小程序会提前新建一个WebView并进行初始化。
页面跳转不再是一个WebView内部的跳转,而是上升到Native View层次上的转换。
页面跳转时,小程序直接用初始化好的WebView进行页面展示,提高加载速度。
基础组件
CSS决定了界面的多样性,但由于浏览器内核的历史性和多样性,同样的一套CSS在不同平台上会带来一定程度的兼容性和性能问题。而微信小程序由于其平台的固定性,可以着力于完善基于固定平台的最优CSS样式库。用户采用基础组件开发,自然地继承了相应CSS的最优性能。
禁用浏览器Dom API
开发者不支持使用标准的Dom API开发网页,最后的渲染工作由微信端的JS库进行操作。而微信小程序采用Virtual Dom,可以减少重绘和重排的次数,提高了页面的性能。如果Dom API暴露给用户,虽然界面的交互和操作上更丰富,但开发者对于Dom操作的随意性反而会降低页面的性能。
总之,微信小程序结合了各种优化策略。在Web层面上虚拟Dom、高性能CSS样式库,原生层面上有WebView预加载,原生模块覆盖等。虽然在开发上建立了一定的限制,但带来了整体性能上的提升。