V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
meishadevs
V2EX  ›  职场话题

一次有意义的前端面试总结

  •  3
     
  •   meishadevs · 2018-03-22 11:58:17 +08:00 · 9874 次点击
    这是一个创建于 2198 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我今天去参加了位于深圳某公司的前端开发工程师岗位的面试,这是我来深圳后参加的第二次面试,感觉这次面试经历比较有趣,也通过这次面试学到了很多东西,所以决定以博客的形式记录下来。

    获得面试机会

    该从哪里讲起呢,就从看到那个公司的招聘信息讲起吧,当我还在江西老家的时候就打算年后来深圳找工作,所以我在来深圳之前就通过 Boss 直聘和一些技术社区查找深圳的前端开发工程师的招聘信息,并投递了部分简历,在某个技术论坛上看到这个公司招聘前端工程师,我便通过 Email 投了一份简历过去,几天后对方回复了我一份邮件,大意是问我何时有空去面试,我当时还在江西老家,告知对方我要在正月十五才会去深圳后,对方很爽快的表示我到深圳后再告知对方,再安排其他时间面试,我到了深圳后发 Email 告诉对方我来深圳了,在元宵节假期结束后的的第一天上班时,对方发来了回复邮件,让 HR 为我安排面试时间,下午 HR 便打电话给我,通知我去面试,并通过 Email 将面试的时间和地址发给了我,感觉比 Boss 直聘上的通知方式要正式的多,在 Boss 直聘上如果对方通知你去面试直接就说你过来面试吧,还要自己再问对方,对方才会告知你面试的地址。

    满是陷阱的笔试

    乘地铁到高新园站出来后便来到了那个公司的所在地,一栋非常高端的写字楼,那个公司就在这个写字楼里,进入公司后便开始笔试,感觉笔试题都很基础,但是里面有很多陷阱,比如第一题要求写出 10 + '20' 的值,然后将计算的结果再加 '20',这题主要考察数字与字符串之间的运算,在 JavaScript 中字符串加上数字,首先需要将数字转换成字符串,然后再进行相加运算,相加的结果仍能是字符串,所以 10 + '20' = '1020',结果再加上'20'为 '1020' + '20' = '102020'。还有一题要求写出 add(4)(5)的实现函数,看到这题后我一脸懵逼,函数不都是只有一个括号吗,这里怎么出现了两个括号,面试结束后我通过在一个前端交流群里问了这个问题,这题考察的是函数柯里化,还有一题要求使用 ES6 的语法实现数组去重等,通过这次面试我也发现了我的很多知识盲区。

    糟糕的自我介绍

    笔试结束后 HR 拿着我的简历和做的笔试题指引我来到了一个会议室,当我在会议室坐下后不久,会议室里进来了一位女士,她就是我今天面试的面试官,互相打了个招呼后,她首先让我做自我介绍,然后我便说道我叫 xxx,今年 xx 岁,来自江西,有一年工作经验,过来是应聘前端开发工程师职位,我说完后她让我再介绍一下之前的工作经历和做过的项目,我因为提前没准备好,说的吞吞吐吐,这次我学到了做自我介绍时要简要的介绍一下个人信息、工作经历和之前做过的项目

    有意义的面试

    自我介绍完成后她便拿着我的简历问我问题。
    面试官:你知道盒模型吗?
    我:盒模型是由 margin、border、padding、width 巴拉巴拉一大堆。
    面试官:我是问你标准盒模型和怪异模型你了解吗?
    我:标准盒模型 width=padding+border+(当时太紧张了,不知道如何回答了)。
    面试官:你知道 JavaScript 中的事件绑定方式吗?
    我:onclick。
    面试官:onclick 不能算是事件绑定的方式。
    我:addEventListener。
    面试官:还有吗?
    我:我知道的就这么多。
    面试官:知道 rem 和 em 吗,他们两个有什么区别?
    我:rem 表示的是相对于网页的根节点然后巴拉巴拉一大堆。
    面试官:知道原型吗?
    我:知道,在 JavaScript 中的继承就是通过原型实现的。
    面试官:那你说说 JavaScript 中实现继承的方式有哪些?
    我:巴拉巴拉一大堆。
    面试官:知道数据的存储方式吗?
    我:localStorage、seesionStorage、Cookie。
    面试官:localStorage 和 sessionStorage 之间有什么区别?
    我:localStorage 可以实现数据的永久保存,sessionStorage 存放的数据,当浏览器关闭后会自动丢失。
    面试官: 知道元素层叠吗?
    我:一脸懵逼,后来不知怎么回事就想起来了,我顺便问了一句是指两个元素,一个在上面一个在下面,两个元素的距离为那个 margin 值大的那个元素的 margin 值吗?
    面试官:如何解决这个问题?
    我:能用 padding 就尽量不要用 margin。
    面试官:知道 call 和 apply 吗?
    我:你能不能在纸上写一下(当时没听懂),两个都可以让对象调用函数,其中 apply 中的第一个参数为调用函数的对象,第二个参数为函数传递的数据,其中 apply 传递数据是数组,call 巴拉巴拉。
    面试官:知道跨域吗?
    我:知道。
    面试官:如何解决跨域问题?
    我:使用 JSONP 和在服务器端设置 CORS。
    面试官:看你简历中还提到了你会组件化开发,那你介绍一下你的项目中哪里设使用了组件化开发?
    我:header 组件用于头部、footer 组件用于脚部、banner 组件用于轮播图。
    面试官:介绍一个组件,并说一个如何设计它的外部接口?
    我:那就介绍 banner 组件吧。
    面试官:好。
    我:banner 组件可以设计一个 JSON 数组,数组中的对象可以设计 url 属性表示点击图片后跳转的链接,image 属性表示图片的地址巴拉巴拉。。。
    面试官:好了你回去等通知吧。

    最后附上我能想起来的笔试题和面试题

    1、10 + '20' = ? 再加 '20' 呢?

    10 + '20' = '1020' 
    '1020' + '20' = '102020'
    

    2、请写出 Ajax 请求中用到的函数

    var xhr = new XMLHttpRequest();
    xhr.open('GET/POST', 'http://localhost:8080?username=meishadevs', true);
    xhr.onreadystatechange = function() {};
    xhr.send();
    

    3、使用正则表达式提取出 url 值为 https://map.baidu.com/x/y/z 中的 map.baidu.com

    /https:\/\/([^\/]+)/.exec('https://map.baidu.com/x/y/z')[1]
    'https://map.baidu.com/x/y/z'.match(/https:\/\/([^\/]+)/)[1]
    

    执行结果

    4、使用 ES6 的方法实现数组去重

    let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3];
    let set = new Set(array);
    let arr = Array.from(set);
    

    5、设计一个函数实现 add(3)(4)

    function add(a) {
    	return function(b) {
    		return a + b;
        }
    }
    
    add(3)(4)
    

    ES6 的写法

    add = a => b => a + b
    add(3)(4)
    

    对 ES6 写法做一个变形

    add = a => (b => a + b)
    

    再变

    add = function (a) {
    	return (b => a + b)
    }
    

    再变

    add = function (a) {
    	return function (b) {
    		return a + b;
    	}
    }
    

    6、使用 Ajax 实现一个表单提交功能,并跳转到提交的地址,(可以使用 jQuery 或 Zepto

    7、在完成第 6 题后使用 Promise 再实现一遍

    8、JavaScript 中的基本数据类型

    Number、String、Boolean、Null、Undefined
    

    9、一道响应式布局的题目

    10、call、apply 的作用与区别
    call 和 apply 都是为了改变函数体内部 this 的指向,它们的第一个参数都是调用函数的对象,call 方法接收由若干个参数组成的参数列表,apply 方法接收的是一个包含多个参数的数组

    例如使用call获取一组数字中的最大值

    Math.max.call(null, 1, 3, 5, 8, 2)
    

    例如使用apply获取一组数字中的最大值

    Math.max.apply(null, [1, 3, 5, 8, 2])
    

    11、标准盒模型和怪异盒模型的区别
    标准盒模型的 box-sizing 属性的值为 content-box
    怪异盒模型的 box-sizing 属性的值为 border-box
    标准盒模型中 width = 内容的宽度
    怪异盒模型中 width = 内容的宽度 + padding + border

    12、em 与 rem 的区别
    rem 表示根节点(html 标签)的字体大小的倍数
    当 em 作为 font-size 的单位时,表示相对于父元素的 font-size 值的倍数
    当 em 作为其他属性单位时,代表自身字体大小的倍数

    13、localStorage 与 sessionStorage 的区别
    使用 localStorage 保存的数据,除非手动清除,否则会永久保存
    使用 sessionStorage 保存的数据仅在当前会话下有效,关闭页面或浏览器后会被清除

    14、元素层叠
    参考张鑫旭大神的文章:深入理解 CSS 中的层叠上下文和层叠顺序

    15、使用原型现继承

    使用 __proto__ 实现继承

    //创建 animal 对象
    var animal = {
        name: "animal",
        
        eat: function () {
            console.log(this.name + " is eating");
        }
    };
    
    //创建 dog 对象
    var dog = {
        name: "dog",
    
        //指向 animal 对象( dog 继承自 animal )
        __proto__: animal
    };
    
    //创建 cat 对象
    var cat = {
        name: "cat",
    
        //指向 animal 对象(cat 继承自 animal)
        __proto__: animal
    };
    
    dog.eat();
    cat.eat();
    

    使用 prototype 实现继承

    //创建 animal 对象
    var animal = {
        name: "animal",
    
        eat: function () {
            console.log(this.name + " is eating");
        }
    };
    
    //创建构造函数 Dog
    function Dog() {
        this.name = "dog";
    }
    
    //创建构造函数 Cat
    function Cat() {
        this.name = "cat";
    }
    
    //设置 Dog 的原型为 animal(Dog 继承自 animal)
    Dog.prototype = animal;
    
    //设置 Cat 的原型为 animal(Cat 继承自 animal)
    Cat.prototype = animal;
    
    //创建 dog 对象
    var dog = new Dog();
    
    //创建 cat 对象
    var cat = new Cat();
    
    dog.eat();
    cat.eat();
    

    16、JavaScript 中事件绑定的方式

    button.onclick = function() {}
    
    button.addEventListener("click", function () {});
    

    17、设计一个函数实现判断一个数据的数据类型是不是数组

    function isArray(num) {
    	return num instanceof Array;
    }
    

    总结

    1、自我介绍没准备好,只介绍了我的个人信息,没有介绍工作经历和做过的项目,说话吞吞吐吐, 2、笔试和面试的问题大部分都是前端开发中的基础知识,只有少部分 ES6 和 jQuery 的内容,可见我前端基础掌握的不够好
    3、没有提前计划好,导致块要超过约定的时间时才到面试地点 4、不管是面试还是笔试不知道的就说不知道,不清楚的地方要多问

    参考链接

    39 条回复    2020-09-15 14:04:50 +08:00
    saozhu
        1
    saozhu  
       2018-03-22 12:20:41 +08:00 via iPhone
    扫了一眼排版,先赞一个慢慢看
    kunluanbudang
        2
    kunluanbudang  
       2018-03-22 12:25:45 +08:00 via Android
    throns
        3
    throns  
       2018-03-22 12:52:41 +08:00 via iPhone
    感觉不像面试经历,面试问题和面试官的提问都记得那么清楚.....
    519395527
        4
    519395527  
       2018-03-22 12:57:18 +08:00 via iPhone
    tcl 大厦 上周我才面过 哈哈哈
    coffeSlider
        5
    coffeSlider  
       2018-03-22 13:03:50 +08:00 via Android
    记忆力真好,我是面完就忘。
    kimown
        6
    kimown  
       2018-03-22 13:16:55 +08:00
    嗯,感谢分享,多看多背 /(ㄒoㄒ)/~~
    noe132
        7
    noe132  
       2018-03-22 13:17:58 +08:00 via Android
    看完了,感觉问的东西算是很基础很基础的了,感觉像 2013 年的 js 面试。。。


    我现在写前端,都是各种模块化组件化,各种类,继承。。根据需要,我还自己写了一个 babel plugin 用来解析 import 语句。

    现在都 2018 了
    但还是可以参考参考这篇 how it feels to learn javascript i 2016
    https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f
    pcar
        8
    pcar  
       2018-03-22 13:40:31 +08:00
    好文
    meishadevs
        9
    meishadevs  
    OP
       2018-03-22 13:48:59 +08:00
    @519395527 你也去哪个公司面试了啊
    yunzhihui666
        10
    yunzhihui666  
       2018-03-22 14:00:22 +08:00
    综合评价:你做事非常认真,做题目认真,总结也认真,是一个前端工程师非常良好的品质。
    同时,趁势打个小广告,我们还缺一个高级前端工程师,欢迎查阅: document.location.protocal + '//' + document.location.hostname + '/t/432673'
    codermagefox
        11
    codermagefox  
       2018-03-22 14:00:49 +08:00
    @noe132 #7 老哥,初级你还想问个啥...
    yunzhihui666
        12
    yunzhihui666  
       2018-03-22 14:03:09 +08:00
    综合评价:你做事非常认真,做题目认真,总结也认真,是一个前端工程师非常良好的品质。
    如果你对我们的面试还满意,我不介意你把我们公司的全称打上嘛:云智惠(北京)投资管理有限公司,我们还缺一个高级前端工程师,欢迎查阅:document.location.protocol + '//' + document.location.hostname + '/t/432673'
    Mutoo
        13
    Mutoo  
       2018-03-22 14:07:39 +08:00
    Exia
        14
    Exia  
       2018-03-22 14:13:14 +08:00
    话说有些原生的 JavaScript 不查查我都不知道写呢,函数柯里化看过也忘记了。
    总觉得问题都是网上能找到答案的东西,背感觉还是不是很好。
    开发中用到很多框架或是技术,这些也是一些时间的积累,有经验了,很多就变体力活了,当然不断优化也是个方向,然后慢慢就会干点别的开发事情了呢。
    jarnanchen
        15
    jarnanchen  
       2018-03-22 14:13:32 +08:00
    我觉得楼主基本功还是很扎实的。祝你面试成功
    meishadevs
        16
    meishadevs  
    OP
       2018-03-22 14:16:01 +08:00
    @jarnanchen 我面试时没回答好,后面的题目的答案大部分是从网上找的
    meishadevs
        17
    meishadevs  
    OP
       2018-03-22 14:19:24 +08:00
    @yunzhihui666 我这篇博客几天前就写好了,怕泄密所以一直不敢发在 V2EX 上,也是怕泄密所以没在博客中写公司的名字
    Arrowing
        18
    Arrowing  
       2018-03-22 14:26:32 +08:00
    @meishadevs 作为一年经验的前端开发者,楼主我觉得你基础很扎实了。
    你文中的女士(不是我)已经看到你的博客啦,哈哈,祝你好运~
    attackonFourier
        19
    attackonFourier  
       2018-03-22 14:26:46 +08:00
    我觉得都还是很基础的东西了吧
    原型这块 __proto__内置的原型链 除了 console 台 在代码中是无法访问的 至于为什么要有内置的原型链 是为了保证继承的特性
    还有一个是外部原型链 供用户操作的 就是通过实例对象通过 constructor 回溯的

    继承的话 除了原型继承 常用的就是类抄写的方式了 不过类抄写是用空间换时间的方案了 而且没有内置的 instanceof 来维护父类 需要自己去做这块的处理
    8qwe24657913
        21
    8qwe24657913  
       2018-03-22 14:49:04 +08:00 via Android
    meishadevs
        22
    meishadevs  
    OP
       2018-03-22 14:52:06 +08:00
    @8qwe24657913 谢谢,学习中
    attackonFourier
        23
    attackonFourier  
       2018-03-22 15:15:28 +08:00
    @8qwe24657913 你给 mdn 代码里有一句话
    var shape = {};

    // Set the object prototype.
    // DEPRECATED. This is for example purposes only. DO NOT DO THIS in real code.
    shape.__proto__ = circle;
    g1165297373
        24
    g1165297373  
       2018-03-22 15:29:43 +08:00
    @noe132 1-2 年的前端开发,这些是很好的面试题的,上来就是 react,vue 的,很多人这些并不一定答得上来
    8qwe24657913
        25
    8qwe24657913  
       2018-03-22 15:39:17 +08:00 via Android
    @attackonFourier 你那是因为动态修改[[Prototype]]会破坏优化(见最上面的 warning),像楼主一样在对象字面量里用是可以的 The __proto__ property can also be used in an object literal definition to set the object [[Prototype]] on creation, as an alternative to Object.create().
    conanskyforce
        26
    conanskyforce  
       2018-03-22 16:07:01 +08:00
    我去,咋感觉像 3 年前的前端面试,不过楼主还是挺用心
    simple11
        27
    simple11  
       2018-03-22 16:33:43 +08:00
    赞排版 看完了
    callmexiaobo
        28
    callmexiaobo  
       2018-03-22 18:35:00 +08:00
    排版不错,看的很舒服,同为江西老表赞一个
    sepld
        29
    sepld  
       2018-03-22 19:29:14 +08:00 via Android
    新手虽然不怎么懂前端,但是看的很认真
    LeungJZ
        30
    LeungJZ  
       2018-03-22 19:29:52 +08:00 via Android
    你不会是带了个录音笔去面试吧,记得这么清楚。
    luohuanlhh
        31
    luohuanlhh  
       2018-03-23 01:45:35 +08:00
    mark
    dongliangnerd
        32
    dongliangnerd  
       2018-03-23 09:51:09 +08:00
    @codermagefox 如果一年不是划水过来的,这个确实太简单了
    codermagefox
        33
    codermagefox  
       2018-03-23 10:31:01 +08:00
    @dongliangnerd #32 我一年,全都能做出来,但是我还是觉得这种程度就差不多了....一年你还真让人面试造火箭啊,我面试的时候就被问过一些很难的,人家开的薪资水平也相对的高很多,就一般来说这种难度差不多了。
    dongliangnerd
        34
    dongliangnerd  
       2018-03-23 22:21:35 +08:00
    @codermagefox 这个要求还是要看个人,自己怎么舒服怎么来呗。我还是想对自己以及以后一起长时间伙伴稍微提高一点标准,不管是从个人发展还是交流的舒适度和不加班的效率追求
    TimCheng
        35
    TimCheng  
       2018-03-26 16:46:40 +08:00 via iPhone
    我想邀请你来来掘金参加秋招求职面试征文活动,你感兴趣的话加我微信:cx923373725 活动链接👉🏼 https://juejin.im/post/5aaf2a95f265da239b413aa1
    kaisinx
        36
    kaisinx  
       2018-04-26 10:28:16 +08:00
    hey,是你啊!工作怎么样了?
    meishadevs
        37
    meishadevs  
    OP
       2018-04-26 22:16:22 +08:00
    @kaisinx 找到工作了
    tianyao123
        38
    tianyao123  
       2019-03-25 17:43:00 +08:00
    很基础的题目啊
    aaronlam
        39
    aaronlam  
       2020-09-15 14:04:50 +08:00
    使用 prototype 实现继承里的 Cat/Dog.prototype.constructor 要修改回对应的构造器把?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3002 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 14:49 · PVG 22:49 · LAX 07:49 · JFK 10:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.