前端研发工程师2019面试记录(2)

0.12字数 101阅读 14

如题,面试前端研发工程师

废话不多说,总结经验是重点

2019年8月27日 下午02:00分的面试邀约
提前到达01:30分到达战场

5张面试题... 其实不难 下面罗列一下个别问题

# 选择题基础题 不马虎不会出问题(略)

# 代码分析题

1.执行这段代码,输出什么结果,为什么
function test () {
    console.log(a)
    console.log(foo())
    var a = 1;
    function foo() {
        return 2;
    }
}

答: 
undefined  (定义了变量,并未初始化)
2          (js预处理 预编译为下面方法)

function test () {
    function foo () {
        return 2;
    }
    var a;
    console.log(a);
    console.log(foo());
    a = 1;
}


2.评价一下代码并给出改进意见
if(window.addEventListener){
    var addListener = function(el, type, listener, useCapture) {
        el.addEventListener(type, listener, useCapture);
    };
} else if (document.all){
    addListener = function(el, type, listener) {
        el.attachEvent("on" + type, function() {
            listener.apply(el);
        })
    }
}

答:
    能快速的给组件增加新的事件的功能
    第二个addListener声明应当写在外面,或是加上var,否则成了全局函数
    没考虑其它的浏览器的兼容性,并且上下定义的函数参数个数不一样
    
改进:
var addListener = function(el,type, listener, useCapture ) {
    if (window.addEventListener) {
        el.addEventListener(type, listener, useCapture);
    } else if (document.all) {
        el.attachEvent("on" + type, function() {
            listener.apply(el);
        });
    }
}


# 问答题

1.如何理解和应用JavaScript闭包
答: 闭包就是,js中函数内部可以读取全局变量,函数外部不能读取函数内部的局部变量

闭包的三大特点为:
1)、函数嵌套函数
2)、内部函数可以访问外部函数的变量
3)、参数和变量不会被回收

闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
应用场景: 
//原生的setTimeout传递的第一个函数不能带参数
setTimeout(function(param){
    alert(param)
},1000)


//通过闭包可以实现传参效果
function func(param){
    return function(){
        alert(param)
    }
}
var f1 = func(1);
setTimeout(f1,1000);


2.HTML5应用程序缓存和浏览器缓存有什么区别?
答:
    HTML5缓存: 利用manifest文件
    离线浏览 - 用户可在应用离线时使用它们
    速度 - 已缓存资源加载得更快
    减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源。


3.link和@import都有哪些区别?
答: 两者都是外部引入CSS的方式
    @import是CSS提供的语法规则,只有导入样式表的作用
    link是HTML提供的标签,不仅可以加载CSS文件,还可以定义RSS,rel连接属性等
    
    加载页面时,link引入的CSS被同时加载
    @import引入的CSS将在页面加载完毕后加载


4.JavaScript实现一个冒泡排序
答: 
思路: 比较两个相邻的元素,如果后一个比前一个大,则交换位置
      第一轮的时候最后一个元素应该是最大的一个
      按照第一步的方法进行两个相邻的元素的比较,由于最后一个元素已经是最大的了,所以最后一个元素不用比较。

function sort(element){
    for(var i = 0; i < element.length-1; i++) {
        for(var j = 0; j < element.length-i-1; j++){
            if(element[j] > element[j+1]){
                //把大的数字放到后面
                var swap = element[j];
                element[j] = element[j+1];
                element[j+1] = swap;
            }
        }
    }
}
var element = [3,5,1,2,7,8,4,5,3,4];
sort(element);


# 笔试结束 面试开始 选择记忆较深的问题

延伸题:

JavaScript的其他排序方法
(1) 插入排序
算法描述:
            1)从第一个元素开始,该元素可以被认为已经被排序
            2)取出下一个元素,在已经排好序的序列中从后往前扫描
            3)直到找到小于或者等于该元素的位置
            4)将该位置后面的所有已排序的元素从后往前依次移一位
            5)将该元素插入到该位置
            6)重复步骤2~5

function insertSort(arr) {
    var len = arr.length;
    for (var i=1; i<len; i++) {
        var temp = arr[i];
        var j = i-1;  //默认已排序的元素
        while (j >= 0 && arr[j] > temp) {  //在已排序好的队列中从后向前扫描
                arr[j+1]=arr[j]; //已排序的元素大于新元素,将该元素移到一下个位置
                j--;
            }
            arr[j+1] = temp;
        }
    return arr
}

(2) 选择排序
算法描述:
            1)假设未排序序列的第一个是最大值,记下该元素的位置,从前往后比较
            2)若某个元素比该元素大,覆盖之前的位置
            3)重复第二个步骤,直到找到未排序的末尾
            4)将未排序元素的第一个元素和最大元素交换位置
            5)重复前面几个步骤,直到所有元素都已经排序。

function selsetSort(arr){
    var len = arr.length;
    var index;
    for(var i=0;i<len-1;i++){
        index=i;
        for(var j = i+1; j < len; j++){
            if(arr[index] > arr[j]){  //寻找最小值
                index=j;   //保存最小值的索引
            }
        }
        if(index != i){
            var temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }
    }
    return arr;
}

等...


# 面试题

1.箭头函数的优缺点: 
    优点是代码简洁
    缺点也是这些,比如代码太过简洁,导致不好阅读
    this提前定义,导致无法使用JS进行一些ES5里面看起来非常正常的操作


2.递归函数的优缺点:
    优点是代码简洁
    缺点: 效率(递归由于是函数调用自身,而函数调用是有时间和空间的消耗的)
    性能(调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出)


3.浏览器内核了解:
    (1) Trident(IE内核) 
    IE从版本11开始,初步支持WebGL技术。IE8的JavaScript引擎是Jscript,IE9开始用Chakra,这两个版本区别很大,Chakra无论是速度和标准化方面都很出色。
    
    (2) Gecko(Firefox内核)
    Gecko的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能
    JavaScript引擎是SpiderMonkey
    
    (3) Presto(Opera前内核) (已废弃)
    引擎的特点就是渲染速度的优化达到了极致,然而代价是牺牲了网页的兼容性。
    
    (4) Webkit(Safari内核,Chrome内核原型,开源)
    Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎
    

4.Webpack工作原理:
    https://segmentfault.com/a/1190000015088834?utm_source=tag-newest
    

5.服务端渲染:
    简单理解是将组件或页面通过服务器生成html字符串,再发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序
    好处: 更利于SEO
          更利于首屏渲染
          
    局限: 服务端压力较大
          学习成本相对较高


6.localStorage大小,存满了会怎么样
    个大浏览器不太一样,大概5M
    存满了应该会报错吧 (存疑)
    

7.尾递归:
    函数调用自身,称为递归;如果是尾调用自身,称为尾递归。
    
    function factorial(n) {
          if (n === 1) return 1;
          return n * factorial(n - 1);
    }
    factorial(5) // 120
    
    上面函数计算5的阶乘,需要保留n个调用记录。 
    如果是尾递归,则只保留一个调用记录:
    
    function factorial(n, total) {
      if (n === 1) return total;
      return factorial(n - 1, n * total);
    }
    factorial(5, 1) // 120
    
    第一个方法,最后调用的是n*function,
    其中(n*function)看做一个整体,合成了一个表达式,
    而第二个方法直接是return的一个function,
    拉起了一个调用栈,而不会像第一个方法中的表达式,他会保留之前的调用帧
    至于加入total参数,是为了保存每次阶乘的结果

面试才刚刚开始不能做到问什么会什么

那就只能尽量把被问过的搞定

推荐阅读更多精彩内容