function isEmptyObject(obj) {// 判断输入参数链表是否为空 for (var name in obj) { return false; } return true; }
function ReverseList(pHead) { if (isEmptyObject(pHead)) {// 调用链表是否为空函数 return false; } var pre = null;//链表的最后一个元素 var next = null;//初始化next为null,下面再赋值 while (pHead != null) {//pHead移动,直至到链表最后一个元素,指向null,结束循环 next = pHead.next;//pHead.next值先赋给next,以免覆盖,next移动 pHead.next = pre;//改变pHead指向,给pHead.next赋值,指向null pre = pHead;//pre移动 pHead = next;//pHead移动 } return pre; }
单链表是否有环
创建哈希表,不过会占⽤较⼤的空间,不是最佳⽅法.( 时间复杂度 O(n) )
1 2 3 4 5 6 7 8 9 10
function judge(list){ var set =new Set(); while(list){ if(set.has(list)){ return true } set.add(list) list=list.next() } }
给节点添加 visited 访问标记 (时间复杂度 O(n)), 不需要额外的空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
function LinkedList(){ var Node=function(){ this.element=element; this.next=null; this.visited=0; //访问标记 } }
function randomString(n) { let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; let tmp = '', i = 0, l = str.length; for (i = 0; i < n; i++) { tmp += str.charAt(Math.floor(Math.random() * l)); } return tmp; }
module.exports = randomString;
Q9 实现类似 getElementsByClassName 的功能
自己实现一个函数,查找某个 DOM 节点下面的包含某个 class 的所有 DOM 节点?不允许使用原生提供的 getElementsByClassName querySelectorAll 等原生提供 DOM 查找函数。
function queryClassName(node, name) { var starts = '(^|[ \n\r\t\f])', ends = '([ \n\r\t\f]|$)'; var array = [], regex = new RegExp(starts + name + ends), elements = node.getElementsByTagName("*"), length = elements.length, i = 0, element;
while (i < length) { element = elements[i]; if (regex.test(element.className)) { array.push(element); }
var arr = ['foo','bar','hello','world']; var count = 1; function getStr(a){ for (var i = 0; i < arr.length; i++) { // indexOf 是es6数组的方法,如果不存在返回-1,存在返回下标 if(a.indexOf(arr[i])<0){
// 递归 let arr = [] function deepTraversal(node) { if(!node) return; arr.push(node) for (var i = 0; i< node.children.length; i++) { deepTraversal(node.children[i]) }
} // 非递归 let arr =[] function deepTraversal(node) { if(!node) return; var stack = [node]; while (stack.length) { var item = stack.shift(); arr.push(item); var children = item.children; for (var i = children.length - 1; i >= 0 ; i--) { stack.unshift(children[i]); } } }
function C(){ var a_args=Array.prototype.slice.call(arguments,0,2); var b_args=Array.prototype.slice.call(arguments,2); A.apply(this,a_args); B.apply(this,b_args); }
function C(...s){ A.call(this,s[0],s[1]); B.apply(this,s.slice(2)); }
function C(...s){ A.apply(this,s.slice(0,2)); B.apply(this,s.slice(2)); }
function C(){ A(arguments[0],arguments[1]); B(Array.prototype.slice.call(arguments,2)); }
var compiled = template(“hello <%=user%>!”); compiled({“user”:”world”}); => hello world!
var compiled = template(“welocm to <%=location%>!”); compiled({“location”:”CVTE”}); => welcom to CVTE!;
1 2 3 4 5 6 7 8 9 10 11
function template(source){ var temp=source; return function(obj){ for(var prop in obj){ var tpl="<%="+prop+"%>"; temp=temp.replace(tpl,obj[prop]); } console.log(temp); } }
Q17 写一个函数,将传进去的数组按深度展开
例子: list:[1,2,[3,4],[5,6,[7,8],9],10,11]
depth 等于 1 时输出
depth = 1 :[1,2,3,4,5,6,[7,8],9,10,11]
depth 等于 2 时输出
depth = 2 :[1,2,3,4,5,6,7,8,9,10,11]
1 2 3 4 5 6 7 8 9
function flattern(array,num = 0) { var newArray = array; for(let i = 0; i < num; i ++) { newArray = [].concat(...newArray) } return newArray; }
console.log(flattern([1,2,3,[4,5,[6,7]]],2))
Q18 实现一个简单的模板引擎
例子:
1 2 3 4 5 6
let template = '我是{{name}},年龄{{age}},性别{{sex}}'; let data = { name: '姓名', age: 18 } render(template, data); // 我是姓名,年龄18,性别undefined
在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过 IP 地址。大家这里或许会有个疑问—-计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。比如 www.hackr.jp。那怎么不一开始就赋予个 IP 地址?这样就可以省去解析麻烦。我们先来了解下什么是 IP 地址
1.IP 地址
IP 地址是指互联网协议地址,是 IP Address 的缩写。IP 地址是 IP 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。IP 地址是一个 32 位的二进制数,比如 127.0.0.1 为本机 IP。 域名就相当于 IP 地址乔装打扮的伪装者,带着一副面具。它的作用就是便于记忆和沟通的一组服务器的地址。用户通常使用主机名或域名来访问对方的计算机,而不是直接通过 IP 地址访问。因为与 IP 地址的一组纯数字相比,用字母配合数字的表示形式来指定计算机名更符合人类的记忆习惯。但要让计算机去理解名称,相对而言就变得困难了。因为计算机更擅长处理一长串数字。为了解决上述的问题,DNS 服务应运而生。
2.什么是域名解析
DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。DNS 是一个网络服务器,我们的域名解析简单来说就是在 DNS 上记录一条信息记录。
1
例如 baidu.com 220.114.23.56(服务器外网IP地址)80(服务器端口号)
3. 浏览器如何通过域名去查询 URL 对应的 IP 呢
浏览器缓存:浏览器会按照一定的频率缓存 DNS 记录。
操作系统缓存:如果浏览器缓存中找不到需要的 DNS 记录,那就去操作系统中找。
路由缓存:路由器也有 DNS 缓存。
ISP 的 DNS 服务器:ISP 是互联网服务提供商(Internet Service Provider)的简称,ISP 有专门的 DNS 服务器应对 DNS 查询请求。
根服务器:ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS 服务器先问根域名服务器.com 域名服务器的 IP 地址,然后再问.baidu 域名服务器,依次类推)
4. 小结
浏览器通过向 DNS 服务器发送域名,DNS 服务器查询到与域名相对应的 IP 地址,然后返回给浏览器,浏览器再将 IP 地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。接下来介绍向服务器发送 HTTP 请求阶段,HTTP 请求分为三个部分:TCP 三次握手、http 请求响应信息、关闭 TCP 连接。
服务器是网络环境中的高性能计算机,它侦听网络上的其他计算机(客户机)提交的服务请求,并提供相应的服务,比如网页服务、文件下载服务、邮件服务、视频服务。而客户端主要的功能是浏览网页、看视频、听音乐等等,两者截然不同。 每台服务器上都会安装处理请求的应用——web server。常见的 web server 产品有 apache、nginx、IIS 或 Lighttpd 等。 web server 担任管控的角色,对于不同用户发送的请求,会结合配置文件,把不同请求委托给服务器上处理相应请求的程序进行处理(例如 CGI 脚本,JSP 脚本,servlets,ASP 脚本,服务器端 JavaScript,或者一些其它的服务器端技术等),然后返回后台程序处理产生的结果作为响应。
它负责根据用户从”视图层”输入的指令,选取”模型层”中的数据,然后对其进行相应的操作,产生最终结果。控制器属于管理者角色,从视图接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示模型处理返回的数据。 这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。 至于这一阶段发生什么?简而言之,首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,接着会调用模型,这一阶段模型会获取 redis db 以及 MySQL 的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,最后浏览器通过渲染引擎将网页呈现在用户面前。
2、204 No Content:请求处理成功,但没有任何资源可以返回给客户端,一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
3、206 Partial Content:是对资源某一部分的请求,该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
3XX——表明浏览器需要执行某些特殊的处理以正确处理请求
4、301 Moved Permanently:资源的 uri 已更新,你也更新下你的书签引用吧。永久性重定向,请求的资源已经被分配了新的 URI,以后应使用资源现在所指的 URI。
5、302 Found:资源的 URI 已临时定位到其他位置了,姑且算你已经知道了这个情况了。临时性重定向。和 301 相似,但 302 代表的资源不是永久性移动,只是临时性性质的。换句话说,已移动的资源对应的 URI 将来还有可能发生改变。
6、303 See Other:资源的 URI 已更新,你是否能临时按新的 URI 访问。该状态码表示由于请求对应的资源存在着另一个 URL,应使用 GET 方法定向获取请求的资源。303 状态码和 302 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。
当 301,302,303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。
7、304 Not Modified:资源已找到,但未符合条件请求。该状态码表示客户端发送附带条件的请求时(采用 GET 方法的请求报文中包含 If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since 中任一首部)服务端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回 304.。