几个让我印象深刻的面试题(二)

前言

原文地址&&我的博客
知乎&&知乎专栏
简书
河南前端交流群官网

上次写了一篇几个让我印象深刻的面试题(一)没看过的同学可以去看哦。
这次文章的题目来源:这里有超过20家的前端面试题,你确定不点进来看看?
如果上面的问题在我这篇文章里没有提到的话,那就说明有些问题可以很容易查得到或者很简单或者我能力有限不能解答出来的。如果有的问题你不会而且我又没有提的那就认为就是我能力有限不能解答出来吧。嘿嘿嘿。开个玩笑,不过可以在下面留言哦!

正文

还是老规矩先给题目,然后在看我的答案,有什么意见可以在留言板提。

  1. 请问a,b,c分别输出什么?
function fun(n,o){
    console.log(o)
    return{
      fun:function(m){
         return fun(m,n);
      }
    };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
  1. 用尽可能多的方法找出数组中重复出现过的元素

例如:[1,2,4,4,3,3,1,5,3]

输出:[1,3,4]

  1. 给定一些文档(docs)、词(words),找出词在文档中全部存在的所有文档
var docs = [{
        id: 1,
        words: [‘hello‘,"world"]
    },
    {
        id: 2,
        words: [‘hello‘,"kids"]
    },
    {
        id: 3,
        words: [‘zzzz‘,"hello"]
    },
    {
        id: 4,
        words: [‘world‘,"kids"]
    }
 ];
findDocList(docs,[‘hello‘]) //文档1,文档2,文档3
findDocList(docs,[‘hello‘,‘world‘]) //文档1
  1. 下面代码会输出什么?
var test = (function(a){
    this.a = a;
    return function(b){
        return this.a + b;
    }
    }(function(a,b){
        return a;
    }(1,2)));
console.log(test(1));
  1. 不用循环,创建一个长度为 100 的数组,并且每个元素的值等于它的下标。
  2. 一个整数,它的各位数字如果是左右对称的,则这个数字是对称数。那么请找出 1 至 10000 中所有的对称数
  3. 以下代码输出结果是什么?
var myObject = {
    foo: "bar",
    func: function(){
         var self = this;
         console.log(‘outer func : this.foo‘ + this.foo);
         console.log(‘outer func : self.foo‘ + self.foo);
         (function(){
             console.log(‘inner func : this.foo‘ + this.foo);
             console.log(‘inner func : self.foo‘ + self.foo);
         })();
    }
};
myObject.func();
  1. 请写出以下正则表达式的详细规则说明
    /^(0[1-9]dd?)?[1-9]d{6}d?$/

/^(1[89]|[2-9]d|100)$/i
/^[w-][email protected][a-z0-9-]+({[a-z]{2,6}}){1,2}$/i

  1. 请写出打乱数组方法
  2. 写出element.getElementsByClassName 的实现方法
  3. 请写出代码输出结果
if(!("a" in window)){
    var a = 1;
}
alert(a);
  1. 请写出代码输出结果
var handle = function(a){
    var b = 3;
    var tmp = function(a){
        b = a + b;
        return tmp;
    }
    tmp.toString = function(){
        return b;
    }
    return tmp;
}
alert(handle(4)(5)(6));
  1. javscript表达式"[]==‘‘"的值是什么,为什么?
  2. Js生成下面html,点击每个li的时候弹出1,2,3......
    //li onclick事件都能弹出当前被点击的index=?
<ul id="testUrl">
    <li>index=0</li>
    <li>index=1</li>
</ul>
  1. map方法是ES5中新增的,要求为ES5以下的环境增加个map方法

答案揭晓

第一题

function fun(n,o){
   console.log(o)
   return{
       fun:function(m){
           return fun(m,n);
       }
   };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);

我们先来一步一步地看。首先是a=fun(0)因为只传了一个参数,console输出的是第二个参数的值,所以毫无疑问地输出undefined

然后到a.fun(1)可以看出,这句话是调用前面fun(0)返回回来的一个对象里面的函数fun,这个fun又把fun(m,n)返回出去。这个时候请注意:这个对象里的fun在返回之前调用了一下fun(m,n),所以console又会被执行,可以确定,它肯定不会输出传进去的1,因为1作为第一个参数传到fun(m,n)里,而console是输出第二个参数的。那么这次会输出啥呢?

好了,不给大家卖关子了,答案是0。可能有人会问了,纳尼?为毛是0,0是哪来的?

要想看明白我的解释,前提是你得清楚闭包。这里用到了闭包。我们知道,闭包有个功能就是外部作用域能通过闭包访问函数内部的变量。其实在运行a=fun(0)的时候,return出来的对象里的函数fun把传进来的这个0作为第二个参数传到fun里面并返回出来这时0得到了保存。所以当运行a.fun(1)的时候其实输出的是之前的0。后面的那两个调用也和这个的原理一样,最后都是输出0。

这里可能会有点绕,需要花点时间来看或者自行去调试。(我已经在尽力表达清楚了,如果还不懂的话就留言吧=.=)。

然后到b,如果前面搞懂了这里就不难了。fun(0)运行的时候会return一个对象出去,后面的一串链式调用都是在调用前面函数返回的对象里的fun,最终导致输出是undefined 0 1 2

最后到c,如果b都搞懂了,到这里基本就没什么难度了。分别会输出undefined 0 1 1

如果还不懂的话建议单步调试一下,如果还是不懂可以在下面留言,我会尽最大能力给你解释。

第二题

用尽可能多的方法找出数组中重复出现过的元素
例如:[1,2,4,4,3,3,1,5,3]
输出:[1,3,4]

我的思路是,先创建一个数组。然后将传进来的数组进行排序。然后再利用sort方法遍历数组,因为它能一次取到两个数然后ab比较如果相等而且result里面又没有重复的就把a推进去。

这是我的代码:

4.5日更新

感谢@倔强的小瓶盖同学指出的问题

function repeat(arr) {
    var result = [];
    arr.sort().reduce(function(a, b) {
        if(a === b && result.indexOf(a) === -1) {
            result.push(a);
        }
        return b;
    });
    return result;
}
//之前问题代码
function repeat(arr){
    var result=[];
    arr.sort().sort(function(a,b){
        if(a===b&&result.indexOf(a)===-1){
            result.push(a);
        }
    });
    return result;
}

3.23日更新

感谢@start-wrap同学提供的方法:

function repeat(arr){
    var result = [], map = {};
    arr.map(function(num){
    if(map[num] === 1) result.push(num);
        map[num] = (map[num] || 0) + 1;
    });
    return result;
}

值得一提的是map[num] = (map[num] || 0) + 1,这句代码的(map[num] || 0)如果map[num]存在,则map[num]+1反之则0+1,个人觉得用得很巧妙。

感谢@早乙女瑞穂提供的淫技巧:

// es6
let array = [1, 1, 2, 3, 3, 3, 4, 4, 5];
Array.from(new Set(array.filter((x, i, self) => self.indexOf(x) !== i)));
// es5
var array = [1, 2, 4, 4, 3, 3, 1, 5, 3];
array.filter(function(x, i, self) {
    return self.indexOf(x) === i && self.lastIndexOf(x) !== i
});

es6思路解说:

array.filter((x, i, self) => self.indexOf(x) !== i)
返回一个数组,该数组由arrary中重复的元素构成(返回N-1次)

new Set( [iterable] )
返回一个集合(重复元素在此被合并)

Array.from( [iterable] )
返回一个数组(将上一步的集合变为数组)

//es5思路解说:

使用indexOflastIndexOf正向判断和反向判断这个元素是不是同一个数(如果是同一个数,则两个方法返回的i是一样的)

第三题

给定一些文档(docs)、词(words),找出词在文档中全部存在的所有文档

我的思路是:把第二个参数的数组用join合成一个字符串,然后用forEach遍历,分别把文档里的words也用join合成一个字符串,利用search方法找每个文档里的words是否包含有arrStr

这是我的代码:

function findDocList(docs, arr) {
    let arrStr = arr.join(""),
    itemStr,
    result = [];
    docs.forEach(function(item) {
        itemStr = item.words.join("");
        if(itemStr.search(new RegExp(arrStr)) !== -1) {
        result.push("文档" + item.id);
    }
    });
    console.log(result);
}
findDocList(docs, [‘hello‘]) //文档1,文档2,文档3
findDocList(docs, [‘hello‘, ‘world‘]) //文档1

第四题

下面代码会输出什么?

var test = (function(a){
        this.a = a;
        return function(b){
        return this.a + b;
        }
}(function(a,b){
        return a;
}(1,2)));
console.log(test(1));

可以看到,这里有两个自执行函数。下面这个自执行函数执行完后向上面这个自执行函数传了个1所以this.a=1,这里的this指向window。然后这个自执行函数返回个函数给test变量。下面调用test(1),这个1传进来后相当于return 1+1所以就输出2。

第五题

不用循环,创建一个长度为 100 的数组,并且每个元素的值等于它的下标。

如果了解Object.keysArray.form的话,这题基本上没啥难度。
答案:

Object.keys(Array.from({length:100}))

哎!等下Array.form不是es6的吗,es5的怎么实现?
代码来了:

Object.keys(Array.apply(null,{length:100}))

如果还不懂可以参考这里的讲解。

第六题

一个整数,它的各位数字如果是左右对称的,则这个数字是对称数。那么请找出 1 至 10000 中所有的对称数

我的思路,先将数字转为字符串,然后利用数组的map方法遍历这个字符串,将字符串全部分开变为数组,然后调用数组的reverse方法,再将翻转后的数组join成字符串,最后对比翻转后的字符串和翻转前的字符串是否相等即可(方法有点愚笨,望大神指教):

function symmetric(){
    var i=1,
    str,
    newStr,
    result=[];
    for(;i<1000;i++){
        str=""+i;
        newStr=result.map.call(str,function(item){
            return item;
        }).reverse().join("");
        if(str===newStr){
            result.push(+str);
        }
    }
    return result;
}

第七题

以下代码输出什么?

var myObject = {
    foo: "bar",
    func: function(){
    var self = this;
    console.log(‘outer func : this.foo‘ + this.foo);
    console.log(‘outer func : self.foo‘ + self.foo);
    (function(){
        console.log(‘inner func : this.foo‘ + this.foo);
        console.log(‘inner func : self.foo‘ + self.foo);
    })();
    }
};
myObject.func();

这题主要考察this指向,个人觉得难度不是太大,因为this已经被我完全承包啦(坏笑脸)。
这题的话只需考虑谁调用的函数this就指向谁。
函数开始执行self=this这里的this是指向myObject的,因为myObject.func()很明显是myObject在调用它嘛,所以头两句console输出的foo都是bar
下面是一个自执行函数,要知道,自执行函数的this一般情况下都指向window这里也不例外,所以,第三个console输出的fooundefined因为在windowfoo没定义。第四个输出的是self.foo这个self就是上面定义的selfmyObject所以,这里的foobar

第八题

请写出以下正则表达式的详细规则说明
/^(0[1-9]dd?)?[1-9]d{6}d?$/
/^(1[89]|[2-9]d|100)$/i
/^[w-][email protected][a-z0-9-]+({[a-z]{2,6}}){1,2}$/i

嘿嘿,正则也算我比较拿手的部分。我来一个一个解释吧,有些正则比较难用语言表达,大家意会意会吧。

第一个:首先^代表的是以它后面的一堆东西为开头$代表以它前面一堆东西为结尾,在这里的意思就是以(0[1-9]\d\d?)?[1-9]\d{6}\d?为开头和结尾的字符串。然后到第一个括号里的意思是匹配第一个字符串为0第二个字符串为1-9第三个字符串为0-9第四个字符串可有可无,有的话匹配1-9,然后这整个括号里面的内容可有可无。问好后面的意思是匹配第一个字符串是1-9然后后面6个字符串匹配0-9最后一个字符串可有可无,有的话匹配0-9。

所以整理整理就是:匹配以0为第一个,1-9为第二个,数字为第三个;第四个可有可无,有的话匹配数字;然后前面这一整坨可有可无。1-9为第五个(如果前面那一坨没有的话,则从第一个算起)然后后面6个都是数字最后一个数字可有可无的字符串,且以它为开头和结尾。

下面是例子:
022222222222 //true
002222222222 //false 因为第二个数字是1-9
02222222222 //第一个括号最后一个数字者最后面的数字省略
0222222222 //第一个括号最后一个数字者最后面的数字省略
22222222 //第一个括号里的内容全部省略
02222222 //d{6}没有满足。

第二个:匹配以1作为第一个,8或9作为第二个又或者以2-9为第一个,数字为第二个又或者匹配100的字符串,并以他们为开头和结尾,忽略大小写。

还是例子比较直观:

18 //true 匹配前面的1[89]
23 //true 匹配[2-9]d
100 //true 匹配100
17 //false
230 //false

第三个:
匹配前面至少一个数字或字母或_或-再匹配@然后再匹配至少一个字母或数字或-然后到再匹配{字母2-6个}1-2个,的字符串,并以他们为开头和结尾忽略大小写。

这个用语言描述太难了,是我不会说话吗,上例子吧:

[email protected]{aw}{ad} //true
[email protected]{ddd}{fs} //true
[email protected]{dw}{ddd} //true
[email protected]{dw} //false {字母2-6个}少了一个即({[a-z]{2,6}}){1,2}后面的{1,2}没满足
@3{dw}{ddd} //false [w-]+没满足
33{dw}{ddd} //false 没@
[email protected]{dw}{d} //false ({[a-z]{2,6}})不符合

第九题

请写出打乱数组方法

4.5日更新

参考这里

// 之前的问题代码
function randomsort(a, b) {
    return Math.random()>.5 ? -1 : 1;
    //用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1
}
var arr = [1, 2, 3, 4, 5];
arr.sort(randomsort);

第十题

写出element.getElementsByClassName 的实现方法
我的思路:先获取页面下的所有元素,然后用split将传进来的多个class分割成数组,然后利两层循环找出符合条件的元素(个人觉得这种方法效率实在低下,就当是抛砖引玉吧,欢迎留言)
代码:

if(!document.getElementsByClassName) {
    document.getElementsByClassName = function(className) {
    var ele = [],
        tags = document.getElementsByTagName("*");
    className = className.split(/\s+/);
    for(var i = 0; i < tags.length; i++) {
        for(var j = 0; j < className.length; j++) {
        //如果这个元素上有这个class且没在ele里面(主要防止多个class加在一个元素上推进去两次的情况)
            if(tags[i].className === className[j] && ele.indexOf(tags[i]) === -1) {
                ele.push(tags[i]);
            }
        }
    }
    return ele;
    }
}

第十一题

请写出代码输出结果

  if(!("a" in window)){
      var a = 1;
  }
  alert(a);

这题主要考察了变量的声明提升,任何变量(es5中)的声明都会提升到当前作用域的顶端。所以这里的代码其实为:

  var a;
  if(!("a" in window)){
      a = 1;
  }
  alert(a);

所以,在if语句执行前a就已经在window中了,所以这里会atert undefined

第十二题

请写出代码输出结果

var handle = function(a){
    var b = 3;
    var tmp = function(a){
        b = a + b;
        return tmp;
    }
    tmp.toString = function(){
        return b;
    }
    return tmp;
}
alert(handle(4)(5)(6));

我们来一步一步看:首先是handle(4),到这里,程序开始运行,创建了一个tmp函数,同时把tmp函数的toString方法重写了,最后返回这个tmp函数。
注意tmp里的a不是传进去的4,不要把tmpahandlea搞混了,所以这里传的4啥也没干。

然后到第二步:handle(4)(5),这里就是执行了tmp函数,这个时候tmp函数的a就是传进来的5,·b就是第一步函数执行的b即3(不懂为何是3的同学再去了解了解闭包吧),最后这个b就等于8。

第三部重复第二步8+6,最后b为14,javascript引擎最后自动调用了toString返回b,所以结果是14。

第十三题

javscript表达式"[]==‘‘"的值是什么,为什么?

这题考察对js==运算符的了解,我们知道==运算符如果两边值类型不一样会把它们转换为相同类型的值再来比较。这题左边是object类型,右边是string类型,所以会把左边的转化为string类型来比较,[].toString()就是‘‘所以最后结果是true

第十四题

Js生成下面html,点击每个li的时候弹出1,2,3......
//li onclick事件都能弹出当前被点击的index=?

<ul id="testUrl">
    <li>index=0</li>
    <li>index=1</li>
</ul>

这题直接按照要求生成对应的html,再给ul绑定个事件,利用事件代理监听是谁被点了,然后输出它们的序号和对应的内容,没啥难度。我的代码:

var ul=document.createElement("ul"),
    lis=[];
    ul.id="testUrl";
for(var i=0,li;i<2;i++){
    li=document.createElement("li");
    li.innerHTML="index="+i;
    ul.appendChild(li);
    lis.push(li);
}
ul.addEventListener("click",function(e){
    alert(lis.indexOf(e.target));
    alert(e.target.innerHTML)
});
document.body.appendChild(ul);

第十五题

map方法是ES5中新增的,要求为ES5以下的环境增加个map方法

个人认为只要对map方法够了解,自然就能封装出来了。嘿嘿,不喜勿喷。给的链接虽然也有一个实现map的方法,但是用到了es5的for in不符合题目,所以我的代码:

if(!Array.prototype.map){
    Array.prototype.map=function(callback,context){
    var len=this.length,
        i=0,
        result=[];
    if (typeof callback !== "function") {
        throw new TypeError(callback + " is not a function");
    }
    context=context||window;
    for(;i<len;i++){
        this[i]!==undefined?result.push(callback.call(context,this[i],i,this)):result.push(this[i]);
    }
    return result;
    }
}

不过我的代码和标准的输出结果还是有点出入的。就是我不处理undefinednull,因为this[i]!==undefined,这两个值是会原样返回的。不过日常的一些需求还是能满足的。欢迎大家提建议哈。

终于打完了,这期就这么多题,希望能对大家有帮助,同时如果有不对的地方请及时指正,欢迎留言。

另外,欢迎大家来围观我封装的一个ajax库 lightings

参考

JS随机打乱数组的方法小结
如何不使用loop循环,创建一个长度为100的数组,并且每个元素的值等于它的下标
MDN map

本文转载于:猿2048?https://www.mk2048.com/blog/blog.php?id=hhacc1hhiab

原文地址:https://www.cnblogs.com/baimeishaoxia/p/12527011.html

时间: 2024-10-15 11:04:09

几个让我印象深刻的面试题(二)的相关文章

几道印象深刻的笔试题

1.java虚拟机在gc的时候为什么会卡一下?gc的策略就哪几种?如何进行优化 2.有学生表student(id, name,gender(性别))和成绩表score(id,score)两张表,请用一个sql查询成绩男女成绩各前三名的学生姓名 3.线程的生命周期是什么?什么是线程安全?如何保证线程安全? 4.二叉树的中序遍历,请分别用递归和非递归方式实现. 5.有个1km长的无序int数组,请问使用什么方式排序,时间复杂度是多少?简单描述如何实现? 6.java会有内存泄露吗?如果会,请解释在哪

让人印象深刻的回答

知乎上那些简短却让人印象深刻的回答 你认为怎样的人生很酷(有趣)? —always stay out of your comfort zone. [为什么部分人会产生「聪明智慧的姑娘都被憨憨的小伙儿搞定了」的印象?] 严肃地说,我觉得,要么姑娘只是看起来聪明,要么小伙儿只是看起来憨··· [怎么看待励志的书籍?] 看再多,那都是别人的人生. [为什么很多程序员.Geek 都喜欢熬夜,而且在后半夜工作效率异常高?] 一个姑娘问我,搞学术的为什么都睡得那么晚,难道只有到晚上才有灵感?不是,姑娘,搞学

9个让人印象深刻的网站 JS 视觉效果

网页设计已经提升到一个整体新的水平,Flash 渐渐失去了地位,逐渐被 HTML/JavaScript/CSS 所超越,而且一样可以实现出 Flash 复杂的特效. 本文介绍 8 个让人印象深刻的网站视觉效果,这些效果都是采用纯 JavaScript 实现的. Viens La 该网站通过你的滚动来显示微妙的动画. Joint London 超简约的设计与独特的导航系统. Lena Sanz 一个视觉丰富的摄影网站,有一个巨大的响应滑块. Skull Candy 视差的不同类型,根据预定义的路径

【转】令人印象深刻的廣告詞

令人印象深刻的廣告詞覺得蠻有趣ㄉ-把它貼上來跟大家分享- 這裡有一百多個- 有些廣告詞也蠻有年代- 哈哈- 全家 = 全家就是你家!麥當勞 = 麥當勞都是為你!7-11 = 有seven - eleven真好!全國電子 = 全國電子就感心耶!motorola = 哈囉!moto威士比 = 啊~~~福氣啦!屈臣氏 = 我發誓,我們最便宜!最佳女主角 = 最佳女主角換你做做看 /我不認識你,但是我謝謝你!DHC = C唄C唄,DHC!中興米 = 有點黏又不會太黏! 崔巢奶粉 = 成長只有一次!克寧奶

那些我印象深刻的建议和教诲

编者按:本文作者余晟,文章首法于其微信公众号“余晟以为”(微信号:yurii-says),授权 36 氪发布.余晟是上回引发热烈讨论的<你的团队里有几条鲶鱼>作者,这次又有新的东西想跟你分享. 人的一生,当然有很多的时间去自己摸索和探究,做出自己的选择:其他人的教诲,很多时候并不会干涉选择,反而会让人少走弯路,更快捷抵达自己的目标.下面,我列了自己印象深刻的教诲(或者说 “建议”),既是对各位的感谢,也希望通过分享让更多人受益. [技术是你的安身立命之本] 这是大学时候中文系的王老师对我说的.

三位印象深刻的老师与往事

三位印象深刻的老师与往事 ① 小学的 A 老师 A 老师是思想品德老师,平常十分随和. 大概是因为课程内容比较少,经常在课堂上聊一些高深 的东西, 给我们这些小屁孩留下一个"上知天文,下知地理,文经武律,无所不通 " 的奇妙印象. 口头禅都是什么 你们以后就懂了. 之类的... 然而,这样的 A 老师却让我非常惧怕. 原因在于,作为一个小学生,我第一次知道了什么是特殊待遇: 上课时一旦和同桌或者前后私聊,立刻就被点名批判一番: 课堂上一旦有问题没人举手回答,必定让我起来谈笑风生: 严抓

三位让我印象深刻的老师

三位让我印象深刻的老师 虽然这是作业..但是...我想起了以前的很多事情....有点不知道怎么从一大堆东西里写点什么了..........写印象最深的三个吧. 走了很远的路,不应该忘记为了什么而出发. L老师 小学时的课外语文老师. 他经常带我们出去看附近的名胜古迹,自己写了一本很厚的教材,背诵翻译文言文,写议论文. 受他的影响,我的语文基础很好,初中高中语文课基本在划水+装逼+睡觉,高考语文110分这样. 他家里的花开了几次了 Z老师 ---------- 初中的历史老师,X班的班主任,心态开

三位印象深刻的老师

小学班主任 -小学的班主任....回忆起来还是很怕怕滴,因为她真的很严厉. -我一直都小心翼翼,可是还是被她抓到过:因为班级活动迟到了两三分钟,被她当着全班的面批评.具体过程不说,到现在还是有一点阴影. -不过想想也算一件好事,这让我能够比较严格地要求自己. -小学六年班主任都是她,所以感情很深厚.她温柔起来也让我很想亲近她:会给我们讲故事,天气变化会提醒我们注意增减衣物. -又爱又怕她让我对她印象深刻. 初中班主任 -初中班主任也带了我一整个初中 -她很爱教育我们,给我们讲道理,看到好文章会都

印象深刻的三位老师

花开花落,岁月如梭.不知不觉,已经大学了,回首眺望,总有那么几个人让你印象深刻,难以忘怀.其中,在读书的时候让我有深刻印象或对我有深刻影响就有三个. 第一个,是在二年级的时候,我现在也只记得她姓黄老师了,很多事情我也忘记了,只知道一点,那就是在考试后的讲评了,她曾立了一个规定,那就是如果你的考试成绩满分,那么,在她讲评的那一节课你就可以自己跑出来玩了,那个时候,我还是很贪玩的,而且上课自己跑出来玩而其他人在听更是激动,为此,为了数学考满分,我还是会很认真去学数学的,也是那个时候,培养了我对数学的