1.JavaScript 实现二分法查找?
二分法查找,也称折半查找,是一种在有序数组中查找特定元素的搜索算法。查找过程可以分为以下步骤:(1)首先,从有序数组的中间的元素开始搜索,如果该元素正好是目标元素(即要查找的元素),则搜索过程结束,否则进行下一步。(2)如果目标元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作。(3)如果某一步数组为空,则表示找不到目标元素。代码:
// 非递归算法
function binary_search(arr, key) {
var low = 0,
high = arr.length – 1;
while(low <= high){
var mid = parseInt((high + low) / 2);
if(key == arr[mid]){
return mid;
}else if(key > arr[mid]){
low = mid + 1;
}else if(key < arr[mid]){
high = mid -1;
}else{
return -1;
}
}
};
var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];
var result = binary_search(arr,10);
alert(result); // 9 返回目标元素的索引值
// 递归算法
function binary_search(arr,low, high, key) {
if (low > high){
return -1;
}
var mid = parseInt((high + low) / 2);
if(arr[mid] == key){
return mid;
}else if (arr[mid] > key){
high = mid – 1;
return binary_search(arr, low, high, key);
}else if (arr[mid] < key){
low = mid + 1;
return binary_search(arr, low, high, key);
}
};
var arr = [1,2,3,4,5,6,7,8,9,10,11,23,44,86];
var result = binary_search(arr, 0, 13, 10);
alert(result); // 9 返回目标元素的索引值
2. 有一楼梯共 M 级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第 M 级,共有多少种走法?
这个问题要倒过来看,要到达 n 级楼梯,只有两种方式,从(n-1)级 或(n-2)级到达的。所以可以用递推的思想去想这题,假设有一个数组 s[n], 那么 s[1] = 1(由于一开始就在第一级,只有一种方法),s[2] = 1(只能从 s[1] 上去 没有其他方法)。那么就可以推出 s[3] ~ s[n] 了。下面继续模拟一下,s[3] = s[1] + s[2],因为只能从第一级跨两步,或者第二级跨一步。
function cStairs(n) {
if(n === 1 || n === 2) {
return 1;
} else {
return cStairs(n-1) + cStairs(n-2)
}
}
3. 递归设计。实现一个函数,给该函数一个 DOM 节点,函数访问其所有子元素 (所有子元素,不仅仅是直接子元素),每次访问子元素的时候,并为其传一个 callback?
// 访问一个 DOM tree,是一个经典的深度优先搜索的算法
function Traverse(DOM,callback) {
callback(DOM);
var list = DOM.children;
Array.prototype.forEach.apply(list,(item)=>{
Traverse(item,callback); // 递归
})
}
4. 介绍一下对 webpack 的认识?
WebPack 是一个模块打包工具,可以使用 WebPack 管理模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包 Web 开发中所用到的 HTML、javaScript、CSS 以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack 有对应的模块加载器。webpack 模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。webpack 的两大特色:1)code splitting(可以自动完成)2)loader 可以处理各种类型的静态文件,并且支持串联操作 webpack 是以 commonJS 的形式来书写脚本,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。webpack 具有 requireJs 和 browserify 的功能,但仍有很多自己的新特性:1)对 CommonJS、AMD、ES6 的语法做了兼容 2)对 js、css、图片等资源文件都支持打包 3)串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对 CoffeeScript、ES6 的支持 4)有独立的配置文件 webpack.config.js5)可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间 6)支持 SourceUrls 和 SourceMaps,易于调试 7)具有强大的 Plugin 接口,大多是内部插件,使用起来比较灵活 8)webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
5. 关于 HTTP2.0 的认识
HTTP/ 2 引入了“服务端推(server push)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。HTTP/ 2 提供更多的加密支持,HTTP/ 2 使用多路技术,允许多个消息在一个连接上同时交差。它增加了头压缩(header compression),因此即使非常小的请求,其请求和响应的 header 都只会占用很小比例的带宽。
6. 对 AMD 和 Commonjs 的理解?
CommonJS 是服务器端模块的规范,nodejs 采用了这个规范。CommonJS 规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD 规范则是非同步加载模块,允许指定回调函数。AMD 推荐的风格通过返回一个对象做为模块对象,CommonJS 的风格通过对 module.exports 或 exports 的属性赋值来达到暴露模块对象的目的。
7.mongoDB 和 MySQL 的区别?
MySQL 是传统的关系型数据库,MongoDB 则是非关系型数据库 mongodb 以 JSON 结构(二进制)进行存储,对海量数据存储有着很明显的优势。对比传统关系型数据库,NoSQL 有着非常显著的性能和扩展性优势,与关系型数据库相比,MongoDB 的优点有:①弱一致性(最终一致),更能保证用户的访问速度:②文档结构的存储方式,能够更便捷的获取数据。
8. 讲讲 304 缓存的原理?
服务器首先产生 ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器,要求服务器验证其(客户端)缓存。304 是 HTTP 状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件。客户端请求一个页面 A。服务器返回页面 A,并在给 A 加上一个 ETag。客户端展现该页面,并将页面连同 ETag 一起缓存。客户再次请求页面 A,并将上次请求时服务器返回的 ETag 一起传递给服务器。服务器检查该 ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应 304(未修改——Not Modified)和一个空的响应体。
9. 用 node 模拟客户端发起请求?
var http = require(“http”);
var request = http.request({
host:”localhost”,
port:”8080″,
path:”/request”,
method:”post”
},function(res){
res.on(“data”,function(chunk){
console.log(chunk.toString());
});
});
request.write(“user=zhang&pass=111”);
request.end(“ 请求结束 ”);// 结束本次请求
10.CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?
CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。import/export 最终都是编译为 require/exports 来执行的。CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。