Tencent Phone Interview
原文链接 http://jasonliao.me/posts/2016-03-26-tencent-phone-interview.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
这篇总结欠了很久了,每次想写的时候,都总有一些事情耽误。在 3 月 14 日的上午,腾讯打来了一个面试电话,但是我在上课就重新安排时间了,说下午两点多再打过来,但是这一天我却等不到他的电话。那种心情只有经历过的人才知道
第二天,15 日下午 4 点 39 分打来了电话,开始了我第二个的电话面试 (引用为面试官,斜体为心理活动,黑体为总结,其他为回答)
廖杰斌同学是吗?先做一下自我介绍吧
我就把自我介绍说了一遍,里面涉及到一个印象最深的项目,和自己的一些情况,主要是前端方面的
那么多项目,你说说哪个项目对你影响最大,对你的成长最有帮助
我分成了两个来回答,对我成长和学习能力有最很大提升的是海口市公共安全联动指挥调度系统,而对于抗压能力,需求的管理方面的提升,就要数长沙烟草一卡通集成平台
那我问一个技术问题吧,一个表单,可以被人看到,却不能被人输入,有什么方法可以做到这一点
可以为表单设备 readonly
属性
还有吗
监听 keydown
事件,然后每当用户输入的时候,再把输入内容清空
还有吗
暂时只想到这两个方法
有了解过取消默认事件吗
啊对,preventDefault
可以达到这个效果的方法有很多,现在就把我能找到的方法都实现一次
<input type="text" readonly />
<input type="text" disabled />
readonly
和 disabled
的区别可以看 W3C 对这两个属性的对比,除了里面的说到的区别之外,还有些浏览器会为 disabled
的表单使用不同的默认样式,如输入的区域变灰。Disabled vs Readonly Form Fields 这篇文章会有更加通俗的解释
input.onkeydown = function (e) {
input.value = '';
}
input.onkeydown = function (e) {
e.preventDefault();
}
但事实上,第一种方式并不可行,它总是会显示你当前输入的单个字符。而使用 preventDefault
则可以达到效果
<input type="text" onfoucs="this.blur()" />
这种方式也可以,或者更加友好的是可以聚焦到下一个表单,这样当我们使用 Tab 来跳转表单的时候,可以跳到这个 "readonly" 的表单的下面,而不会失焦后不知道跳到哪里
How can I make a field readonly in a Web form?
再问一个技术问题,一个按钮有两种情况,一种是用 CSS 控制样式的,另一种是用 JavaScript 动态生成的,现在在页面中取消了,你要怎么找它出来
如果是 CSS 控制样式的话,我们肯定可以通过 class
或者 id
在 DevTool 里搜索到,因为 DevTool 支持对选择器搜索并高亮元素
如果是 JavaScript 动态生成的话,方法也可以像上面一样找呀
如果就是找不到呢
那就可以断点调试呀,可以看到哪一步出错了
那现在有一个这样的情况,一个函数 A,被函数 B 和函数 C 调用,断点在 A 里,已经在断点处停了,怎么知道是 B 调用还是 C 调用
其实我们从上两个问题就一直纠缠,问题并不是很清楚,多次确定后才知道题目意思,所以在沟通上总是说不到面试官的点,其实是在考察调试的熟练程度,而这个问题我也是不知道的,平时并没有注意到。然后我就尝试去说说想法
这个我还真不清楚,可能在调试的地方,应该可以看到这个函数的 caller
之类的属性吧
之后我去 DevTool 看的时候,一眼就可以发现在调试面板的下面,会有一个 Call Stack 的下拉子面板,这个面板可以看到整个运行过程和函数的调用情况。还有一个方法就是进入一个函数的断点之后,在那一排调试按钮里可以找到 Step out of current function,也可以往上跳到这个函数的调用函数中去
你知道怎么对一个网页进行性能优化吗
我们可以减少 HTTP 的请求,例如将多个 .js
或者 .css
压缩成一个,而对于图片的话,可以使用 CSS Sprite 或者 Icon Font
那为什么要减少 HTTP 请求呢
因为在 HTTP 请求的时候,要建立 TCP 连接,这样就会有多个等待时间和响应时间
但是现在 HTTP 可以建立一个 TCP 连接,然后发送多个请求了,那为什么还有减少 HTTP 请求呢
我方了
但是只有一个请求,总比多个请求快的,不是吗
那你平时下载东西的时候,例如迅雷,它就是要发送多个请求来提高速度的,那为什么网页的时候,就要减少 HTTP 请求呢
迅雷不是 P2P 吗?请求到不同的资源,当然快呀
不好意思,我不太清楚 :(
那我们为什么要减少 HTTP 请求呢, 减少 HTTP 请求有这样几个优点
1. 可以减少 DNS 请求所耗费的时间
2. 减少服务器压力,我想这也是面试官提出迅雷的意图,看我们知不知道 C/S 和 P2P 两种方式的区别
3. 减少 HTTP 请求头,因为每个请求都会携带 cookie 和其他的一些头信息,服务器响应也会带回一些 cookie 和一些头信息,这也会影响带宽性能
那还有其他的优化方式吗
还可以使用 CDN 来加载我们所需要的资源
那 CDN 是怎么工作呢
还好我有做功课
当你在发送请求的时候,会有一个域名解析成 IP 的过程。在 DNS 解析的时候,会依次找到你本地的 host,如果没有找到就会到当地运营商的 DNS 去解析,一般叫 Local DNS,然后 Local DNS 把域名从后到前进行解析,解析到主域名的时候就会得到一条 cName,然后就根据这个 cName 请求到 cName 本身的 DNS 服务器上。如果这个 DNS 有做 CDN 服务,它就会从 Local DNS 的请求中拿到运营商 IP,知道你的请求来自哪里,然后根据你的地点,通过一定的算法,找到最接近你,最适合你的 CDN 节点的 IP 返回给你,你再用这个 IP 请求获取资源的时候,就会快很多了
还有其他方式吗
可以利用缓存机制,缓存又分强缓存和协商缓存两种
在浏览器去加载一个资源的时候,会先根据这一个资源上一次 HTTP 返回报文的 Expires 和 Cache-Control 这两个 header 来判断这个资源是否属于强缓存,如果属于,不向服务器发送请求,直接从缓存中加载,HTTP 状态码为 200,而返回的报文和数据都是上一次请求时保存起来的
如果不属于强缓存,浏览器就一定会发送这个请求,而服务器就会根据 HTTP 请求报文中的 If-Modified-Since 和 ETag 与服务器的这个资源的 Last-Modified 和 If-None-Match 判断是否属于协商缓存,如果属于,HTTP 状态码为 304,那么浏览器就又会在缓存中拿到我们的资源
嗯嗯,好,那你有了解 CSRF 吗
有的,跨站请求伪造。他的原理是这样的,一个用户登记了网站 A,并且记住了密码,下次自动登录。这里如果这个用户再访问网站 B,如果网站 B 里嵌有对网站 A 发送请求的脚本,那么就会在该用户不知情的情况下,向网站 A 发送了请求,又因为这时用户保存了密码,所以就相当于网站 B 拿了用户的权限,去做用户不知道的事
那 CSRF 能存在的根本原因是什么
我觉得是因为 HTTP 是无状态的,所以要靠 cookie, session 来保证一个请求是不是来自于某一个用户,但是却无法保证这个请求是不是该用户批准的
那怎么防止 CSRF
我知道的有两种方式吧
验证 HTTP Referer 字段,这个字段记录了 HTTP 请求的来源地址,一般是用户在页面里触发的请求,都是这个页面本身所在的域。但如果是从危险网站发送过来的请求,HTTP Referer 就会指向危险网站的域。服务端可以在后台对该字段进行判断,如果非同域的请求应该拒绝
请求中加入 token,如果黑客伪造的请求没有这个 token 或者 token 的类型和内容不对,就可以判断是否为 CSRF 攻击。我们可以把这个 token 放在 session 中。在请求时拿出来与参数中的和 token 对比
嗯,好,来说说前端的新技术
现在比较火的有 React 呀,还有 Angular2,Vue.js 等等吧
React 是 React.js 还是 React Native
React.js,没有玩 RN
那你用 React.js 有没有做点什么东西出来
没有,只有做一点点很小很小型的应用,并没有很深入的了解
那你平时是怎么学习前端的
我会逛逛 github 呀,关注一些大牛,订阅一些关于前端的资讯
你还有什么要问我的吗
昨天不是说两点打过来吗?怎么现在才打,还有你对我的表现感觉怎么样?
哦哦哦,昨天临时开会了,所以没有打过去,不好意思了
没有没有,我还以为你不会打过来了
没有没有,你表现得不错,很多问题的原理你都有了解,但是还更应该深入一点,而且还要把学的东西用于实践
好的,谢谢!
那没什么,我们今天就到这里了,好吗?
好的,再次感谢!
不用不用,那拜拜~
好的,再见~
Wrap up
其实也真像那个面试官所说的,我虽然对每个问题都有了解,但是却不够深入,还有在回答问题上,太过的被动,没有主动地去扩展。对于技术,宁缺勿滥
正如 ZEALER 说的
慢几步,深几度