1.HTTP
HTTP协议
HTTP详情可参考:https://www.cnblogs.com/qdhxhz/p/8468913.html
http1.0、http1.1、http2.0的区别
- http1.1开始支持长连接(keep-alive),http1.0每次请求完成后就会断开连接。
- http1.1支持只发送header信息,节约了宽度。http1.0不支持
- http1.1支持host域,使一台物理服务器可存在多个虚拟主机,http1.0一个ip只能对用一台主机。
- http1.1新增了
Entity tag
、If-Unmodified-Since
、If-Match
、If-None-Match
等多个控制缓存的策略。http1.0主要通过If-Modified-Since
、Expires
进行缓存。 - http1.1新增了24个错误状态的响应码。例如:409:请求资源和资源当前状态发生了冲突。
- http2.0使用了多路复用的技术,可对同一连接并发的处理对个请求。http1.1也可以建立多个tcp连接来支持并发请求,但开销更大。
- http2.0支持header压缩,http1.1不支持,只能以纯文本传输。
- http2.0开始支持服务器推送功能,允许服务器主动将资源推送到客户端,从而节约客户端请求数。http1.1只能依次请求获取资源。
2.如何建立可持续迭代
目前软件开发常存在着需求频繁变更,功能多次修改的问题,这就导致我们的将进行多次的迭代开发,可持续的迭代开发将降低我们的开发风险。
传统开发和迭代式开发的区别
- 迭代式开发不要求一次性获得完整的需求,它允许需求逐渐加深理解完善。而传统开发是瀑布式的,需要有完整的需求,依次往下开发,这将导致中间如果需求出现变更将对整体进度参生的较大的影响。
- 迭代式软件开发采用持续集成的软件开发方式。传统的开发模式是按模块进行开发。这将导致只有项目后期才有成品软件可交付。迭代式开发将整个开发过程分为了数个迭代,每个迭代结束均有可执行的产品交付。
- 传统的开发模式是首先完善子模块功能,当子模块开发完成后组和成一个可运行软件。迭代式开发会先抽取基础功能,开发中只考虑主流程,忽略分支流程。这样我们就可以快速交付客户一个可执行版本,方便客户调整需求。
- 迭代式开发,能够直观的了解软件开发进度,同时也方便客户及时对描述不清的需求做调整。
如何制定一个迭代计划
- 合理的进行工作量评估。因为每个迭代都包含需求分析、设计、开发、测试,所以因人而异,合理安排每一项工作时间相当重要。
- 功能优先级评估。优先开发最基础最重要的功能。
- 制定合理的迭代计划。根据实际情况制定合理的迭代周期,定期的完善迭代,持续更新项目功能。
- 理智对待需求变更。一次迭代的完成很可能伴随着需求的变更。我们应该充分理解客户的意图,根据需求变更的大小合理调整迭代计划,并告知客户需求变更可能带来的交付延期。
- 合理的利用持续集成工具。例如svn、git、maven 、自动化测试等。
3.webpack热部署
webpack热部署依赖于html-webpack-plugin
,简称HMR。
webpack将会对我们手写的代码(module
)进行编译打包,生成chunk
文件。然后基于chunk
生成build
文件。build文件包含所有的逻辑和代码,可以直接在浏览器上执行。
当代码被修改保存后,webpack会重新进行打包,并将改的的模块发送到浏览器,浏览器用新的模块替换旧的模块从而实现局部更新页面,而非整体刷新效果。
实现原理:
webpack-dev-server
使用express
启动本地服务,当浏览器访问资源的时候做出对应响应。- 服务端和客户端使用websocket实现长连接,方便代码更新后服务端向客户端推送新的打包文件。
webpack
监听源文件的变化,当改变时即重新编译。- 每次编译都会生成hash值、已改动模块的json文件、已改动模块代码的js文件
- 编译完成后通过socket向客户端推送当前编译的hash戳
- 客户端的websocket监听到有推送的hash戳时,进行文件对比。
- 新旧hash一致,走缓存
- 新旧hash不一致,通过ajax和jsonp向服务端获取最新资源。
- 使用
hotApply()
进行文件替换,达到热更新的目的。
4.nginx代理
nginx是轻量级HTTP服务器。其支持FastCGI,提供了简单的负载均衡和容错。
- nginx相较于Apache消耗更少的内存,支持更多的并发连接(可同时支持50000个并发响应)
- nginx稳定性更高,可用于反向代理,且使用BSD许可协议,可扩展性更大,支持用户修改源码然后进行发布。
- nginx支持热部署,master管理进程和worker工作进程相分离,使得nginx能够提供热部署,且可在7*24小时不间断服务的前提下更新配置项、日志等功能。
- nginx单次请求响应更快,并发请求响应也较为快捷。
ngnix缓存:proxy_cache_path
、proxy_cache_use_stale
、proxy_cache_valid
等。
#proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
5. CORS代理
CORS(跨域资源共享):通过服务端设置Access-Control-Allow-Origin
和Access-Control-Allow-Credentials
来实现的一种跨域访问方式。
如果跨域请求需要操作cookie,则必须满足如下条件:
- 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
- 浏览器发起ajax需要指定withCredentials 为true
- 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名
$.ajax({
...
xhrFields: {
withCredentials: true // 前端设置是否带cookie
},
crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie
...
});
6.垃圾回收机制
js中垃圾回收机制以标记清除为主,引用计数为辅的方式进行垃圾回收。
6.1标记清除
工作原理
当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
工作流程
- 垃圾收集器会给所有存储在内存中的变量加上标记,
- 然后去掉正在环境中的变量标记,以及被环境中变量引用的变量标记。
- 之后再被标记的变量则是准备删除的变量。
- 回收带有标记的变量内存。
6.2 引用计数
工作原理
跟踪每个变量的引用次数。当引用册数为0时则回收该变量的内存空间。
工作流程
- 声明一个变量时,将一个引用类型的值赋给该变量,那么引用次数加1。
- 如果该值再被其他变量引用则引用次数再加1。
- 如果引用该值的变量被赋予了其他值,则引用次数减1。
- 当引用次数为0时,则证明无法再访问该变量了,将会在下次垃圾回收时回收内存空间。
对应循环引用,由于两个变量都至少被引用了一次,则将永远无法回收,造成内存不足。
6.3 GC优化策略
1. 分代回收
和Java回收策略思想是一致的,也是V8所主要采用的。目的是通过区分“临时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对象”区(tenured generation),减少每次需遍历的对象,从而减少每次GC的耗时。
2.增量GC
每次处理一点,下次再处理一点,如此类推。
6.4 出发时机
IE6的垃圾回收是根据内存分配量运行的,当环境中存在256个变量、4096个对象、64k的字符串任意一种情况的时候就会触发垃圾回收器工作。
IE7做了调整,触发条件不再是固定的,而是动态修改的,初始值和 IE6 相同,如果垃圾回收器回收的内存分配量低于程序占用内存的15%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,如果回收的内存高于 85%,说明大部分内存早就该清理了,这时候把触发条件置回。
GC 时,将停止响应其他操作,这是为了安全考虑。这将会对游戏造成较大的影响,所以是游戏类引擎必须考虑的问题。
6.5 内存模型
js内存空间主要分为堆和栈。
- 堆:类似一颗树,主要存放引用类型和函数。
- 栈:后进先出,主要用于存放基础数据类型(包括常量)
- 队列:先进先出的数据结构。
6.6 常见的内存泄漏原因
- 全局变量
- 被遗忘的定时器和回调函数
- 大量闭包操作
- 对dom操作的引用遗留