「前端」2019.10 猿辅导实习生面

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_26377547/article/details/102740065

面试官是个小姐姐,本来有些紧张的,后来突然好了。
视频面试,时间大概50分钟的样子。

自我介绍

这个就不用说了,基本操作。

基础知识

1. 从URL输入到浏览器,到页面显示在浏览器中,这个过程你能说一下吗?

老生常谈,实习生面应该不会问的太细,所以简单说了一下流程:

  1. URL经过DNS解析成IP地址:
  • 首先到浏览器缓存当中查找是否有缓存,没有则下一步
  • 到操作系统缓存当中去查找是否有缓存,没有则下一步
  • 到路由器缓存当中查找是否存在缓存,没有则下一步
  • 通过ISP的DNS服务器查找是否有IP地址,没有则下一步
  • 通过根服务器递归查询
  1. 获取到服务器IP地址后:
  • 通过ARP协议,找到服务器的MAC地址
  • 与服务器建立TCP连接(3次握手)
  1. 与服务器建立TCP连接后:
  • 向服务器发送HTTP请求
  • 服务器接收到请求并处理后,返回HTML/CSS/JS代码
  1. 从服务器接收到HTML/CSS/JS代码后:
  • 浏览器会先对HTML代码进行解析,构建DOM树
  • 对CSS代码进行解析,构建CSS规则树
  • 加载JS代码(过程会阻塞DOM树和CSS规则树的构建,可以使用<script>标签的async/defer实现异步加载/执行)
  • 根据CSS规则树和DOM树,计算各元素位置,构建渲染树(Render Tree)
  • 调用操作系统的Native GUI的API绘制页面

这里强烈安利一个博客:https://github.com/ljianshu/Blog/issues/24

2. HTML事件

这点真没看过,直接坦白不会,然后就过了(恶补!!!)

3. JS的事件循环

这点粗略看过但是实在想不起来了,然后也过了(恶补!!!)

4. 你的项目为什么会选择Ant Design作为UI框架

现象级的UI框架。Ant Design可以说是又好用又好看,API文档也十分详细。

5. 都说setTimeout()会在Promise对象前执行,能解释一下其中的原理吗?

项目里唯一用到的Promise对象只有Ajax请求了,这点粗略看过但是也没想起来(拉出去打死,一连三题都答不上)
详细的原理,这篇博客解释的很不错:https://juejin.im/post/5b191d585188257d831e338e

** 6. 求一个二叉树的高度(递归+非递归)**
leetcode 104:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

Node {
  value: Number
  left: Node
  right: Node
}

我竟然只写出了递归的,严厉批评自己:

// 递归
const maxDepth = (root, n = 0) => {
  if (!root) return 0
  n++
  let n1 = 0, n2 = 0
  if (root.left) n1 = maxDepth(root.left, n)
  if (root.right) n2 = maxDepth(root.right, n)
  return Math.max(n, n1, n2)
}

非递归没写出来,结束之后仔细想了想:
用队列或者栈就能实现(BFS/DFS)

const maxDepth = root => {
  if (!root) return 0
  let queue = [root], n = 0
  while (queue.length) {
    let arr = []
    while (queue.length) {
      let curr = queue.shift()
      if (curr.left) arr.push(curr.left)
      if (curr.right) arr.push(curr.right)
    }
    n++
    queue = arr
  }
  return n
}

7. 实现一个每隔n秒输出一个数的print()函数
这个在平时做题的过程中遇到过这个坑,用了最简单的方法实现:

var print = (num, time) => {
	for(let i=1; i<=num; i++) {
		setTimeout(console.log(i), time*i);
	}
}

这个方法是用到了作用域原理,let声明的变量只在循环当中有效,循环结束后就释放了,因此setTimeout()每次都是取到循环内的值。但是如果使用var声明,由于var声明的变量会被提升至全局作用域当中,而setTimeout()执行的时间又在循环完成之后,循环完成之后累加器早就已经加到了最大值,再输出的时候,就会输出n个最大值。

var print = (num, time) => {
	for(var i=1; i<=num; i++) {
		(function(i) {
			setTimeout(console.log(i),time*i);
		})(i)
	}
}

这个方法就是使用到了立即执行函数以及闭包的原理,每一次迭代都会立即执行其中的匿名函数,并将迭代的值i传入其中。(这个方法当时已经在控制台写出来大部分了,然而忘了要在立即执行函数里面写一个函数才能正确执行,然后时间也到了,就放弃了,有些可惜)

总结

这次面试真的比面腾讯那次好很多了,有了先前经验,再加上之前准备的内容,至少能比较好地说出自己所了解的知识。
不知道这次的情况怎么样,不管怎样还是得继续加油!

人生如逆旅,我亦是行人。

猜你喜欢

转载自blog.csdn.net/qq_26377547/article/details/102740065