Skip to content

阿里巴巴前端面试经历 #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
54017 opened this issue Apr 2, 2016 · 8 comments
Closed

阿里巴巴前端面试经历 #1

54017 opened this issue Apr 2, 2016 · 8 comments
Labels

Comments

@54017
Copy link
Owner

54017 commented Apr 2, 2016

阿里2017前端工程师实习offer总结

前言

博主不久以前刚拿到阿里巴巴蚂蚁金服的前端开发offer,经历了五轮技术面,一轮HR面,历时约三个星期(哈哈连面试官都喷了我的面试体验)。 在这里分享一下面试经历希望帮助一下大家,一些面试题的答案和部分整理的小知识会贴在后面。

技术一面

刚内推完1个小时,北京蚂蚁金服就打来了电话,是一个声音很有磁性的大哥哥(?)。自己完全没有准备,因为没有想到会这么快,紧张死了。 然后问了一些前端方面的知识,如下

  1. JavaScript基本数据结构
  2. IE和Chrome事件模型的区别
  3. 事件委托
  4. 跨域问题,JSONP的原理
  5. 常见HTTP状态码
  6. Style标签放置的最佳位置
  7. GET和POST的区别
  8. 常见行内元素和块级元素
  9. cookie和session区别
  10. 项目和实习经历

一面大概就是这么多,持续了十几分钟,博主一面后以为药丸了,因为太紧张答的很不好,行内元素和块级元素列举了四五个后居然就说不下去了,然后大哥哥很贴心的说出一个个标签然后让我回答是行内还是块级. 居然还有二面,真的很感激这位面试官。

技术二面

一面完的第二天二面电话就来了,应该是技术总监,很有威严的感觉,约了下午两点,然后很准时的打过来了,期间博主拉着两个小伙伴在我旁边听我面试壮胆。问的问题都比一面深入了些,下面列出一些还记得的问题

  1. jQuery对象和JS的Element有什么区别(考实时性)
  2. jQuery对象是怎么实现的
  3. 给定一个链表找出中间的对象
  4. jQuery级联的实现
  5. WebGL渲染的过程
  6. position定位问题(absolute, relative)
  7. 闭包原理
  8. 3点一刻时针和分针的夹角

电面持续了半小时,问了挺多东西的,可是博主都忘掉啦。 答的也不算特别好,jQuery对象的实现都没答出来,药丸。 然后最后的问题,我一直答夹角为0度,233333,蠢成猪了。面完之后觉得二面过不了了,正在伤心的时候,面试官又打过来说要我去北京现场面试 ,说去联系HR后再通知我。

技术三面(视频)

过了三天后面试官又打过来说安排视频面试(好开心,不用现场面),然后博主赶紧剃了胡子,洗了脸,剪了头发。视频过来居然看的到面试官的脸啊哈哈哈哈,还以为只能他看我呢。 面试官应该还是技术总监,萌萌哒的,所以不是特别紧张。问了很多问题,持续了一小时,期间面试官还对我笑了2333333。

  1. Cache-control
  2. 项目中遇到的困难
  3. 浏览器渲染过程
  4. 手写一个冒泡排序处理事务(这里应该是考模块化和易扩展的类的思想,博主GG)
  5. 圣杯布局多种解决方式
  6. React的diff原理和组件化思想
  7. 浏览器缓存策略
  8. canvas的使用
  9. 树叶飘落动画的实现
  10. React Native
  11. 想在杭州还是北京工作

在面试中面试官说我所面的部门是蚂蚁金服里的蚂蚁聚宝,大多数技术人员在北京,不过博主还是说想去杭州,因为担心在北京活不下去哈哈。

技术四面

过了很久很久大概一个多星期吧,阿里杭州那边的电话打过来了,接电话的时候高兴的要命,以为是HR呢,然后发现还是技术。问的问题挺少的,主要问博主实习的工作,然后问了响应式布局和H5开发(博主不太明白主要需要说哪方面,乱说了一通)。

技术五面

又过了挺久吧,第五个电话从杭州打过来了,又以为是HR,又白开心了一下,我说我都面了五面了,面试官苦笑一下说我的面试体验太差了哈哈。 然后问的问题也比较少,主要是模块化思想,组件化思想吧,最后挂电话的时候说聊的不错,博主也觉得还不错2333333.

HR面

再一次过了很久很久,第六个电话打过来啦,博主当时在雨中前行着,和HR说不太方便,然后HR说只需要15分钟,然后我担心挂掉后就不会再打过来了,然后就开始面试了,之前就听说阿里HR有一票否决权,所以还很是担心,不过这位HR大姐姐还是很温柔的,问的问题杀伤性也不太大

  1. 和同学做过的最好的项目(考团队合作?)
  2. 项目中遇到的困难
  3. 有什么业余爱好(弹吉他,HR笑着问参加过比赛了吗,有没有粉丝,博主说没有,HR沉默了)
  4. 实习经历(博主大二暑假在UC实习过哒)
  5. 有没有女朋友(excuse me? HR说的时候自己都笑的花枝招展了)

博主最后问了HR阿里的工作氛围啦,HR说和UC很像,都是阿里系,轻松愉快萌萌哒的。 然后说最后的结果要等校招完统一通知,当时听到就觉得心痛,要是内推没过那岂不是GG了,校招又不能参加了,绝望的挂掉了电话。 不久以后三面技术官问我什么时候可以去实习,然后希望我早点去,博主也想早点去,可是有必修课啊啊啊,然后婉拒了。 面试官无奈的说就按照你的时间来吧。 当时还不敢跟他说HR拖着我offer呢。 不过过了几个小时后,offer就发到博主手机和邮箱啦,开心到哭泣。

好了,水了这么多,上一点点干货吧

小知识点

JS一切皆对象

数组!!!! a = [1, 2]....b[0] = a;
b[0][0] === 1; a[0] = 2; 那么b[0][0] === 2

运算符优先级

&&的优先级比||要高

行内元素&块级元素

在标准文档流里面,块级元素具有以下特点:

  1. 总是在新行上开始,占据一整行

    //他们将处在同一行
    <div>一二三</div>
    <span>四五</span>
    //他们将处在不同行
    <span>四五</span>
    <div>一二三</div>
  2. 高度,行高以及外边距和内边距都可控制;

  3. 宽带始终是与浏览器宽度一样,与内容无关;

  4. 它可以容纳内联元素和其他块元素。

行内元素的特点:

  1. 和其他元素都在一行上;
  2. 高,行高及外边距和内边距部分可改变;
  3. 宽度只与内容有关;
  4. 行内元素只能容纳文本或者其他行内元素。不可以设置宽高,其宽度随着内容增加,高度随字体大小而改变,搜索内联元素可以设置外边界,但是外边界不对上下起作用,只能对左右起作用,也可以设置内边界,但是内边界在ie6中不对上下起作用,只能对左右起作用

ChildNodes && Children

<p title="The test paragraph">
    <strong>fsdsad</strong>
</p>

document.getElementsByTagName('p')[0].childNodes.length === 3
<p>后的换行符为一个文本节点,<strong>为一个节点<\strong>后的换行符为一个节点

变量/函数提升

第 1 种: function foo(){...} (函数声明)

第 2 种: var foo = function(){...} (等号后面必须是匿名函数,这句实质是函数表达式)

只有函数声明可以被提升

Position

  1. 对于position: absolute,元素定位将相对于最近的一个relative、fixed或absolute的父元素,如果没有则相对于body;
  2. position absolute / fixed 会脱离文档流,其他不会

写一个XMLHttpRequest

if (window.XMLHttpRequest) {
    var request = new XMLHttpRequest();
} else if (window.ActiveXObject("Microsoft.XMLHTTP")) {
    var request = new ActiveXObject("Microsoft.XMLHTTP")
}
request.open("GET", url, true) //第三个参数是异步
request.onreadystatechange = function() {
    if (request.readyState == 4) {
        if (request.status == 200 || request.status == 302) {
            alert(request.responseText);
        }
    } 
request.send();
}

readyState5种状态

状态 含义
UNSENT 0 open()尚未调用
OPENED 1 open()已调用
HEADERS_RECEIVED 2 send()已调用,收到响应头
LOADING 3 正在接受响应主体
DONE 4 响应完成

POST提交数据的方式

application/x-www-form-urlencoded

最常见,默认的方式
提交的数据按照query string的方式传递,键和值都会被URI转码比如title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

multipart/form-data

使用表单上传文件时,必须让form的enctyped变为它,一下为一个请求示例

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

首先生成了一个boundary用于分割不同的字段,为了避免与正文内容重复,boundary很长很复杂,然后Content-Type里指明数据是以multipart/form-data来编码的。 消息主体里按照字段个数分为多个结构类似的部分,每部分都是以boundary开始

POST, GET区别

  • GET用来从服务端获取数据,POST用于上传或者修改数据
  • GET大小限制在2KB以内,POST一般没有限制
  • GET参数在URL,POST参数在请求主体中(也就是用send发送),安全性POST高
  • 部分浏览器会缓存GET请求的response,以至于相同的GET请求会得到相同的response即使服务端的数据已经改变,POST不会被缓存
  • 使用XMLHttpRequest时,POST需要显示指定请求头(因为Post一般含有entity-body)
  • xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;"); //用POST的时候一定要有这句 (Content-Type可以不一样)

JS同源策略

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。

同源策略:

浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。从一个域上加载的脚本不允许访问另外一个域的文档属性。

比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。

http://localhost:8080/test.html

<html>  
     <head><title>test same origin policy</title></head>  
     <body>  
         <iframe id="test" src="http://localhost:8081/test2.html"></iframe>  
         <script type="text/javascript">  
             document.getElementById("test").contentDocument.body.innerHTML = "write somthing";  
         </script>  
     </body>  
</html>  

http://localhost:8081/test2.html

<html>  
    <head><title>test same origin policy</title></head>  
    <body>  
        Testing.  
    </body>  
</html>  

这样是不可以的permission denied.

跨域方法

  1. JSONP( only GET )

从外部通过<script>引用的文件和当前文档属于同一个域, 这也是之所以可以调用JS中的属性方法对当前文档DOM进行操作。
JSONP就是利用<script>标签的跨域能力实现跨域数据的访问,请求动态生成的JavaScript脚本同时带一个callback函数名作为参数。其中callback函数本地文档的JavaScript函数,服务器端动态生成的脚本会产生数据,并在代码中以产生的数据为参数调用callback函数。当这段脚本加载到本地文档时,callback函数就被调用。

第一个站点的测试页面(http://localhost:8080/test.html):

<script>  
    function test_handler(data) {  
         console.log(data);  
     }  
 </script>      
 <script src="http://localhost:8081/test_data.js">  

服务器端的Javascript脚(http://localhost:8081/test_data.js):

test_handler('{"data": "something"}');

  1. 图像ping
  2. CORS

浏览器渲染过程(Chrome)

  1. 浏览器获得HTML构建DOM Tree, 获得CSS构建CSSOM (当遇到JS/script时,DOM构建过程会被吊起,需要等待JS执行完毕,当JS全部执行完后,触发DOMContentLoaded)
  2. 通过DOM Tree和CSSOM构建Render Tree
  3. 计算layout (size, position)
  4. 绘制
  5. 渲染层合并(transform opacity只触发这个阶段因此速度快)

为了更好的用户体验渲染引擎会尽快的展示出页面内容,它不会等到所有HTML都被解析再来构建渲染树, 当main thread(而不是Speculative)遇到Script标签时(只要遇到并不需要等待其网络返回和执行)Chrome会执行绘制和渲染层合并操作

当没有script标签时,如果link在\body前,firefox会重绘制导致FOUC,而Chrome会等待css加载完毕(和放在head中行为相同)

标签位置

最佳实践是将link标签置于script标签前(否则有FOUC)。script最佳实践是放在/body前(放在head会导致白屏现象)

BFC(块级格式化上下文)

一个BFC是一个至少满足以下一个条件的盒子:

  1. float不为none
  2. overflow不为visible
  3. display为table-cell, table-caption或者inline-block, flex, inline-flex
  4. position不为static或者relative
  5. 根元素

特征:

  1. 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流);
  2. 处于同一个BFC中的元素相互影响,可能会发生margin collapse;
  3. 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此;
  4. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
  5. 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算;
  6. BFC的区域不会与float的元素区域重叠

BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。(一个元素不能同时存在于两个BFC中

边距塌陷

  1. 相邻块级元素
  2. 父元素,子元素
    当没有border, padding, inline content或者clearance隔开父子元素的margin-top(bottom)和margin- top(bottom)时
  3. 空盒子(没有border, padding, inline content, height, min-height把盒子的margin-top和margin-bottom隔开的话会产生边距塌陷)

clear

相关的floats: 处于同一个BFU的处于该块前面的floats

  1. 运用到non-floating块
    这个non-floating块将会被向下移直到其border-edge在相关的floats的margin-bottom下(因此可以去除边距塌陷)
  2. 运用到floating块
    这个floating 块将被下移至其margin边缘在相关floats的margin边缘下(这会影响该floating块后续floating块,因为后续的floating块不能比前面的position高)

attachEvent & addEventHandler

微软IE6, 7, 8支持attachEvent, 它只支持冒泡事件模型

addEventListener支持捕获和冒泡,先捕获后冒泡

事件委托

document.addEventListener('click', function(e) {
    if (e.target = 'xxx') {
        ...
    } else if (e.target = 'yyy') {
        ...
})

注意父子元素

<div class="wrapper">
    <div class="content">
        我是子元素
    </div>
</div>
document.getElementById('wrapper').addEventListener('click', function(e) {
    console.log("wrapper")
});

document.getElementById('content').addEventListener('click', function(e) {
    console.log("content")
});

即使用定位absolute将子元素content移到父元素外,点击子元素会触发父元素的click事件(事件委托的机制,当子元素事件被触发,事件会向上传递)

Cache-Control

请求头包括: no-cache, no-store, max-age, max-stale, min-fresh, only-if-cached(只从cache里面拿)

响应头包括: public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age. 默认为private

private: 私有缓存,常见就是浏览器里内置的缓存

public: 公有缓存,常见的是代理缓存

  • 请求头中的Cache-Control为no-cache, 缓存服务器会执行validation, 否则如果请求的资源没有过期的话缓存服务器会直接发回这个资源,有了 no-cache 缓存服务器无论资源是否过期都会去validate
  • 请求头中的Cache-Control为Max-age=0, 请求链路上所有cache都会revalidate,通过if-modified-since字段,如果origin server 发现not modified则返回304(不会发送资源来节约带宽)。 当Max-age = n时表示接收在n这个时间里保持新鲜的资源
  • 响应头中的Cache-Control: max-age=259200 (max-age=0, must-revaliate 和 no-cache相同),设置freshness时间
  • Cache-Control "max-age=3600, must-revalidate"
    it is telling both client caches and proxy caches that once the content is stale (older than 3600 seconds) they must revalidate at the origin server before they can serve the content. This should be the default behavior of caching systems, but the must-revalidate directive makes this requirement unambiguous.
  • 响应头中的Cache-Control: no-cache告诉cache无论何时不管怎样必须revalidate

ETag

ETag(EntityTags)是URL的tag,用来标示URL对象是否改变,这样可利用客户端(例如浏览器)的缓存。由服务器首先产生ETag,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。服务器使用它来判断页面是否已经被修改,如果未修改返回304,而不必重新传输整个对象。
户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。我们常见的是使用If-None-Match.请求一个文件的流程可能如下:
  

  1. 客户端发起HTTP GET请求一个文件;  
  2. 服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"1ec5-502264e2ae4c0")(假设服务器支持Etag生成和已经开启了Etag).状态码200。 
  3. 客户端发起HTTP GET请求一个文件,这个时候客户端同时发送一个If-None-Match头,这个头的内容就是我们第一次请求时服务器返回的Etag:1ec5-502264e2ae4c0
  4. 服务器判断发送过来的Etag和计算出来的Etag是匹配的,不返回200,返回304,让客户端继续使用本地缓存。

new & Object.create

new Test()
//做的工作如下
1. create new Object() obj
2. set obj.__proto__ to Test.prototype
3. return typeof Test.call(obj) === 'Object' ?  Test.call(obj) : obj;
Object.create(Test.prototype)
//做的工作如下
1. create new Object() obj
2. set obj.__proto__ to Test.prototype
3. return obj;

所以你应该明白了,如果构造函数返回了一个对象(非primitive value),那么就返回这个对象,否则返回函数内创造的继承了原型链的对象。 当return null时,还是会返回obj即使typeof null是object

Cookie & Session

Cookie

如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。

这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。

如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。

因为cookie会在所有的请求中都被附上,例如图片。所以将图片等静态资源放在其他不需要cookie的域名下会节约带宽

Session

Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

cookie 和session 的区别:

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。 cookie为字符串,session可以存储服务端支持的各种数据类型

2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

5、所以建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中

@54017 54017 added the gossip label Apr 2, 2016
@dengal3
Copy link

dengal3 commented Apr 7, 2016

全文都在“哒“哒“哒”强行卖萌:p

@54017
Copy link
Owner Author

54017 commented Apr 7, 2016

@dengal3 excuse me? 我数了一遍全文就三个哒

@daix6
Copy link

daix6 commented Apr 7, 2016

🌚如果不认识楼主,大概会以为楼主是女生💃💃

@54017
Copy link
Owner Author

54017 commented Apr 7, 2016

@daix6 你高兴就好咯 (shabby

@daix6
Copy link

daix6 commented Apr 7, 2016

@dengal3 我相信她也这么觉得:smiley:

@dengal3
Copy link

dengal3 commented Apr 7, 2016

@daix6

@daix6
Copy link

daix6 commented Apr 11, 2016

是一个声音很有磁性的大哥哥(?)。
然后博主赶紧剃了胡子,洗了脸,剪了头发。视频过来居然看的到面试官的脸啊哈哈哈哈,还以为只能他看我呢。 面试官应该还是技术总监,萌萌哒的,所以不是特别紧张。问了很多问题,持续了一小时,期间面试官还对我笑了2333333。

@Telanx
Copy link

Telanx commented Jun 16, 2016

博主太牛了,大三就会这么多

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants