由浅入深的前端面试题 和矫情的“浪漫主义”诗句

好吧,我承认太标题党了,这篇文章是通过一道前端面试题引出的纯技术讨论。我先要矫情无比的从中外诗歌说起。

传统的佛学经典里,被世人熟知的有这样一句话:“一花一世界,一叶一菩提,一木一浮生,一草一天堂,一砂一极乐,一方一净土,一笑一尘缘,一念一清静。”

昔时佛祖拈花,惟迦叶微笑,既而步往极乐。从一朵花中便能悟出整个世界,得升天堂,佛祖就是佛祖,谁人能有这样的境界。

同时,早在18世纪,英国伟大的浪漫主义诗人Black名为《天真的暗示》的诗中,也类似写道:"To see a world in a grain of sand, and a heaven in a wild flower",一颗沙里一个世界,一朵野花一座天堂。

转念,虽卑为码农,我们写出的代码,却彰显了功力:菜鸟和大神之间的差距,往往工程线上卑微的几行代码,便有天壤之差。

一道系列面试题,在JS知识体系中虽沧海一粟,但考察点充分评判面试者的能力。
管中窥豹,期待读者有不同想法与我讨论。

题目背景

题目是我在《effective javascript》一书中提取的。这一星期陆陆续续面试了不少于10个人,其中不乏工作履历突出的候选者。
但是很遗憾没有能完全在较短时间内有较高质量的回答。

题目前身

这道题可以分为前后两个部分,第一部分很简单,一般有一定JS OOP基础的候选者应该都可以答好:

一个社交网络有一组成员(member),每个成员有一个自己的名字,和存储其朋友信息的列表。请实现这样一个Member构造器。

正确答案不难理解:

function Member (name) {
    this.name = name;
    this.friends = [];
}

是不是非常简单。它的典型错误包括但是不限于:

function Member (name) {
    this.name = name;
}
Member.prototype.friends = [];

关于方法和属性是应该放在原型上,还是构造函数中,如果您不明白的话,是时候补一补原型原型链的知识了。推荐给大家看一下我的同事颜海镜早在3年前的一篇文章。

同样,这道题上我会顺便考察一下面试者对JS中变量的存储方式,包括堆栈存储的不同情况和引用赋值的掌握情况。

题目变身

以上是对JS基础的考察,但是在这道题目的基础上,我进行了更深一步提问。希望对候选者的临场思维、JS基础甚至一些设计能力,又更进一步认识。

我要实现一个带环社交网络(社交圈):

var a = new Member('Alice');
var b = new Member('Bob');
var c = new Member('Carol');
var d = new Member('Dieter');
var e = new Member('Eli');
var f = new Member('Fatima');

a.friends.push(b);
b.friends.push(c);
c.friends.push(e);
d.friends.push(b);
e.friends.push(d, f);

这种情况下,需要实现一个inNetwork方法,判断某目标成员是否在另一个对象成员的社交圈中。规定:顺着社交链能找到目标成员,就认为在社交圈中。否则,不在其社交圈。

解题思路

如果刚接触到这样的题目,尤其是在面试现场,作为面试者很可能会慌乱一下。这时候,需要做的就是先准确分析题目。
根据题目,画出符合上述题目代码的实例化网络:

实例社交圈图示
实例社交圈图示

接下来思考,搜索意味着需要遍历整个社交网络。我们应该:

1)以单个根节点开始,

2)然后添加发现的节点,

3)移除访问过的节点,防止死环

最终实现:

Member.prototype.inNetwork = function (target) {
    var visited = {};
    var worklist = [this]; // 用于存放社交链上的个体信息,初始时以“自己”作为根节点

    while (worklist.length > 0) {
        // 将worklist里的最后一项成员删除并取出
        var member = worklist.pop();
        // 如果存在环的情况,需要避免重复访问
        if (member.name in visited) {
             continue;
        }
        visited[member.name] = member;
        if (member === target) {
            return true;
        }
        // 将当前成员的朋友列表加入worklist当中,他们都在根节点的社交链上
        member.friends.forEach(function(friend) {
            worklist.push(friend);
        })
    }
    return false;
}

我在代码中加上了注释,如果您还不明白也没有关系。建议去跑一下程序,进行debugger和console,尝试去理解。

测试:

a.inNetwork(f) // true
f.inNetwork(a) //false

哈哈,果然Alice能通过朋友圈查找到Fatima,而Fatima却不能反向找到Alice!当然,这样我认为是违反人类社会常识的。但是,谁让他是题目呢?

一道简单的题却覆盖了很多知识点,比如:while循环中的流程控制(continue),数组的基本方法(pop,forEach,push),for...in等等。

它的典型错误包括但是不限于:使用对象承载worklist,然后用for...in循环遍历worklist。

这样做的问题在于:for...in循环并没有要求枚举对象的修改与当前循环保持一致。事实上,标准规范规定了:

“如果被枚举对象在枚举期间添加了新的属性,那么枚举期间并不能保证新添加的属性能够访问”。

总结

这道题考察了面试者包括JS OOP在内的多项基础,尤其是后半道考察了候选者的思维能力、反应能力。如果读者不能理解,欢迎留言问我。或者去查阅:《effective javascript》一书。

扯回原诗句,谈一下感悟,在天体的转动和岁月的轮回中,我们分明的感受到每一个个体所拥有生命周期的单薄无力,在宏大的宇宙观中恐怕渺小不及沧海一粟。诗句的后半句拿出来共勉:“Hold infinity in the palm of your hand, and eternity in an hour 把无限放在你的手上,永恒在一刹那里收藏”。

在前端快速迭代发展的学习中,作为初学者,往往面对浩瀚的知识海洋望洋兴叹,此时基础便是那能够收藏“永恒和无限”的潘多拉魔盒。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,568评论 25 707
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • 前段时间,不知在哪看到一段话:爱,就是和他在一起吃好多好多顿饭。 特别喜欢这句话。 因为我是吃货。因为,这句话让我...
    凉茶的浅墨素笺阅读 349评论 3 3
  • “为尔憔悴尽,不愿忧伤终老。” (壹) 梦想,就像一个精致的吊篮 让人见上一面就心生喜欢 曾经那上面坐着我的父亲 ...
    肥嘉阅读 164评论 2 0
  • 朋友的姐姐今年已经三十五岁了,还没有结婚。她的家里人也很担心,毕竟已经三十五岁了,朋友也劝他姐姐,还是早点结婚吧。...
    西克里阅读 1,002评论 2 1