去哪儿秋招AI笔面试
typeof/instanceof/Object.prototype.toString 区别
📌 回答
- typeof 运算符返回一个字符串,表示操作数的类型,返回的结果包括:number、string、boolean、undefined、object、function、symbol、bigint。
- typeof 有一定局限性,比如 typeof null 是 object,typeof 不能区分数组、普通对象、Date、RegExp 等。
- instanceof 运算符用于检测某个对象是否出现在对应构造函数的原型链上。
- instanceof 受限于全局环境,不同的全局环境下构造函数的原型链是不同的。比如,Iframe 的环境中,instanceof 无法判断对象是否是 Array 的实例。
- Object.prototype.toString 方法返回一个表示该对象的字符串。
- 可以通过 call、apply 方法改变 this 指向,从而实现对任意对象的类型判断。并且,不会受到全局环境的影响。同时,返回的结果也可以精确判断,比如 Object.prototype.toString.call([]) 返回 [object Array],Object.prototype.toString.call(new Date()) 返回 [object Date]。
实现 Vue 模版引擎的基本指令
🔍 展开代码
html<!DOCTYPE html> <html> <head> <style> div { margin: 20px 0; } </style> </head> <body> <!-- Block 1 --> <div v-if="1 + 1 === 2" class="div1"> “去哪儿 ”认识到在线旅游市场的用户需求已经逐渐变化... </div> <div v-else-if="1 + 1 === 2" class="div-else-if-after-true-if"> 这个 v-else-if 紧跟在一个 true 的 v-if 后面,所以它不应该显示。 </div> <!-- Block 2 --> <div v-if="1 + 1 !== 2" class="div2"> 2012年12月,去哪儿顺利通过PCI认证... </div> <div v-else-if="1 + 2 === 3" class="div3"> 2021年8月,中国信息通信研究院发起的“卓信大数据计划”... </div> <div v-else-if="false" class="div4"> 2022年1月,去哪儿旅行App获得移动互联网应用程序(App)安全认证证书... </div> <!-- v-show elements --> <div v-show="true" class="div5"> 2023年8月21日,去哪儿平台数据出境申报获得国家网信办批准... </div> <div v-show="false" class="div6"> “去哪儿”为旅游者提供国内外机票、酒店、会场、度假和签证服务的深度搜索... </div> <!-- Non-directive element --> <span class="span1"> “去哪儿”是通往中国旅游市场,以及接触广大在线旅游消费者的通行证... </span> <script> const rootElement = document.querySelector('body'); const children = Array.from(rootElement.children); // 预处理:收集每个元素的 DOM 节点和指令信息(静态结构,不依赖实时DOM) const elementInfos = children.map(element => ({ element: element, directive: findDirective(element) // 待实现:识别元素的指令(v-if/v-else-if/v-show) })); let ifBlockMet = false; // 跟踪v-if链是否已有条件满足 // 遍历静态结构,处理每个元素的指令逻辑 for (let i = 0; i < elementInfos.length; i++) { const { element, directive } = elementInfos[i]; if (!directive) { ifBlockMet = false; continue; } // 获取指令表达式并求值 const directiveValue = element.getAttribute(directive); const result = expressionFun(directiveValue)(); // v-if逻辑 if (directive === 'v-if') { if (result) { ifBlockMet = true; } else { ifBlockMet = false; element.parentNode.removeChild(element); } } // v-else-if逻辑 else if (directive === 'v-else-if') { const prevInfo = elementInfos[i - 1]; const prevDirective = prevInfo ? prevInfo.directive : null; // 合法性校验:前序必须是v-if/v-else-if,且当前链未满足 if (!/v-if|v-else-if/.test(prevDirective) || ifBlockMet) { element.parentNode.removeChild(element); continue; } if (result) { ifBlockMet = true; } else { ifBlockMet = false; element.parentNode.removeChild(element); } } // v-show逻辑 else if (directive === 'v-show') { if (!result) { element.style['display'] = 'none'; } } } /** * 判断元素是否包含v-if/v-else-if/v-show指令 */ function findDirective(element) { const dis = ['v-if', 'v-else-if', 'v-show']; for (const d of dis) { if (element.hasAttribute(d)) { return d; } } return undefined; } /** * 将表达式字符串转为可执行函数 */ function expressionFun(attrValue) { return function () { return eval(attrValue); }; } </script> </body> </html>OSI 七层模型以及每一层的作用?
📌 回答
- 物理层:负责比特流的传输,包括电气特性、光学特性、物理介质和物理连接等。这一层,涉及到的概念有:网线、光纤、网卡、双绞线、集线器等。
- 数据链路层:在相邻节点传输帧,提供差错的检测、纠正以及 MAC 寻址等。这一层涉及到的概念有:以太网协议、ARP、交换机等。
- 网络层:端到端的寻址和路由的选择,负责把数据报文送达到目标主机。这一层会涉及到 IP 协议、路由表、子网掩码等。
- 传输层:能够借助 TCP/UDP 协议,实现端到端传输,并提供端口管理等功能。
- 会话层:负责建立、维护和终止会话。这里涉及到 RPC、SQL Session 等技术。
- 表示层:负责数据的加密、压缩和解压缩,确保数据能够被正确地表示,进一步保证应用层能正确处理数据。比如 TLS/SSL 就是在这一层实现的。
- 应用层:负责应用程序的通信。涉及到的协议有很多,比如 HTTP、HTTPS、FTP、SMTP、POP3、DNS 等。
如何实现可靠传输?
📌 回答
- 数据分段与编号:每个报文段都带有自己的一个序号,服务端可以按照序号进行数据排序和重组,避免数据的乱序问题。
- 确认应答机制(ACK):接收方收到数据后,会发送一个确认应答报文给发送方,确认数据已经被正确接收。如果出现 ACK 丢失现象,发送方会对数据进行重传。
- 超时重传机制(RTO):基于 RTT 动态平滑计算,在一定时间内如果有数据没有收到确认应答,则认为数据发送失败,进行重传。
- 滑动窗口机制:发送方可以同时发送多个报文,而不必等待接收方确认应答。接收方可以根据接收窗口的大小,来控制接收方可以接收的数据量。
- 流量控制:发送方可以根据接收方的窗口大小 RWND 来控制发送数据的速率,避免发送方发送的数据过快,导致接收方处理不过来。
- 拥塞控制:发送方根据网络的拥塞情况,调整发送数据的速率,避免网络拥塞。
拥塞控制算法以及彼此之间的配合关系?
📌 提示
- 慢启动:初始化阶段拥塞窗口大小为 1,每收到一个 ACK,拥塞窗口大小指数增长。这个机制,用于快速探测网络容量。
- 拥塞避免:当拥塞窗口大小超过阈值时,进入拥塞避免阶段。拥塞窗口大小线性增长,避免网络拥塞。
- 快速重传:当发送方收到 3 个重复 ACK 时,立即触发快速重传机制,重传丢失段。
- 快速恢复:当发送方检测到丢包以后,阈值和窗口大小减半但不会到 1,避免了吞吐量的剧烈下降。然后,拥塞窗口大小线性增长,直到达到阈值。
- 总结:指数增长探测带宽,到阈值之后线性增长并进入稳定阶段;检测到丢包会进入快速恢复,不必等待超时。整体遵循 AIMD 算法——正常时加性增,丢包时乘性减。
给定一个数组,你可以对其中一个数字加一。要求新数组能够满足以下公式结果最大化:
