• 前端实习面试题答案自解(二)--持续更新


    百度第二次

    一面

    1.闭包

    对我而言,闭包其实就是防止某些数据被js自动回收。可以重复利用。

    那么闭包的用处也就产生了,其实就是将有可能被回收的数据进行重复的利用。

    var arr=[];
    var demo = ()=>{
      for(var i=0;i<3;i++){
        arr[i]=function inc(){
          console.log(i);
        }
      }
    }
    demo();
    arr[0]();//3
    arr[1]();//3
    arr[2]();//3

    以上这个错误例子使我们正常使用代码的时候产生的错误。因为js内存回收的机制,所以导致所有的都被回收了。也就发生了这样的错误。那么我们可以使用闭包来避免

    var arr=[];
    var demo = ()=>{
      for(var i=0;i<3;i++){
        arr[i]=(function inc(){
          console.log(i);
        })()
      }
    }
    demo();
    arr[0];//0
    arr[1];//1
    arr[2];//2

    顺便说一下,在es6中提供了新的方式来解决这类问题,就是使用let类型声明变量

    var arr=[];
    var demo = ()=>{
      for(let i=0;i<3;i++){
        arr[i]=function inc(){
          console.log(i);
        }
      }
    }
    demo();
    arr[0]();//0
    arr[1]();//1
    arr[2]();//2

    具体为什么看我上一个答案自解里面有let的相关解释就可以了。

    2.作用域链

    所谓的作用域链就是查找数据变量的数据

    以下是很简单的代码,一旦碰到console.log(a),会自动找a变量,那么在demo对象里面声明的a是最近的,那么显示的变量就是2。

    var a=1
    var demo = ()=>{
      var a=2
      console.log(a);
    }
    demo();//2

    看一个更多的

    var a=1
    var demo = ()=>{
      var b=2;
      (function demo1(){
        (function demo2(){
          console.log(a);
        })()
      })()
    }
    demo();

    这个很明显输出的一定是1。我们都知道一个方法就是一个作用域,那么在最内层的作用域中没有那么就往它更外部的查找,直到找到此种变量或者出现错误的时候才会停止。

    那么我们可以使用栈的方式来解释这个现象

    window对象
    window对象
    demo
    window对象
    demo
    demo1
    window对象
    demo
    demo1
    demo2

    以类似栈的形式来解释这个。当我们在demo2中查找的时候就会从最上层一直查找到window,如果找不到那么就报错。内存回收的时候就是从上层一个一个进行回收,每当回收的时候,内部所定义的方法或者变量除非外部有引用,否则就会被销毁不存在。 

    3.垃圾回收制

    2题内最后部分。。。说的可能不是特别清楚,不过大概应该还是可以看懂的

    4.垃圾回收制的循环引用问题

    关于这个问题。。。。说真的看完解释以后发现这个真的是一个比较古老的问题了。

    首先要确定一下俩个空间里面分别存储的都是什么。

    栈内存存储的是基本的数据类型,比如undefined、null、boolean、number、string。

    堆内存存储的是引用类型的值。、

    栈内存使用的一级缓存,所以数据都会被调用之后直接被释放。

    堆内存使用的二级内存,生命周期是需要某些垃圾回收的算法来进行释放。所以一般它使用的速度比较慢。

    垃圾回收算法大约有俩种

    1.mark and sweep(标记清除)

    现在大部分浏览器都使用这种方式来进行内存的回收。大概就是变量进入执行环境的时候进行标记(标记为进入环境),变量离开环境的时候(函数执行结束)标记为离开环境。那么在给所有变量都进行标记之后,每次都去掉被标记的变量。

    2.reference counting(引用计数)

    这种方式大多在低版本的IE使用这种方式,这种也是很容易发生内存泄露的问题。如果某个变量声明之后将一个引用类型赋值给变量时该值的引用次数加1,当这个变量指向一个其他的值的时候那么该值的引用次数减1。当他的引用次数减少到0的时候会被系统回收。

    所谓的垃圾回收循环利用的方式就会在引用计数的这种方式中发生,

    var a=document.getElementById('element');
    var b={};
    a.pro = b;
    b.pro = a;

    这样dom元素就会始终都绑定在上面了,所以导致它一直在处于引用位置,那么也就发生了内存泄露。

    5.原型链

    对于js原型链实际上就是一个类似查找的一个路径。prototype原型的引用有多个需要说的点。

    总的来说这个图片就囊括了所有的原型链的知识。

    首先要明白,在js中万物皆对象。第二个我们需要知道__proto__、prototype和constructor这三个名词。

    constructor(构造函数)、__proto__(隐式原型)、prototype(显示原型)

    function Foo() {};
    var f1 = new Foo;

    以上面这个方法声明当做例子。

    function Foo() {};
    var f1 = new Foo;
    console.log(f1.constructor===Foo);

    以上部分其实就类似java中的类声明。Foo就是一个构造函数。f1就是我们声明的实例对象。那么也就是很好理解constructor(构造函数)的含义了。

    function Foo() {};
    var f1 = new Foo;
    console.log(f1.__proto__===Foo.prototype);//true

    以上部分就是Foo的原型指向的其实就是实例对象所具有的__proto__指向的是原型对象

    function Foo() {};
    Object.prototype.a=1
    var f1 = new Foo;
    console.log(f1.a);//1

    那么原型链依据刚刚的图就很容易理解了。类似上述代码。我们想使用f1的实例对象查找到a的值,但是我们在Foo构造函数中没有声明该种变量的值,所以就需要沿着原型链取查你想找的数据,在js中所有对象的最终指向都是Object(通过__proto__查找)。当然如果没有查找到的话那么就直接报错。

    6.浏览器的兼容(说几个CSS说几个JS)

    对于css3的兼容属性不太好。例如属性的动画等,大多都需要加上-webkit-(chrome浏览器等)、-moz(火狐浏览器等)-、-o(opera)-等。还有3d变换中的声明2d或者3d的动画。对于css还有不同浏览器的默认外边距不同。也就是说我们在开始的时候需要使用*进行一下初步设定。

    js的对于兼容我记得最清楚的就应该算是ajax的开始的对象声明了。不同浏览器的确实声明不同。还有就是对于我们想取出当前触发事件的对象event 需要使用var e = event || window.event。还有对scrolltop的获取。

    对于这个问题实在是我觉得回答起来很费劲,因为这个问题实在是太过笼统。给我的感觉就是对你的项目或者敲得代码的问题,或者干脆面试官暂时没想到什么问题问你。。。。

    7.PromiseA+规范

    promiseA+规范实际上就是类似一个规则。

    一般它是由以下组成的。

    1.不管任何操作,最后都会返回一个promise对象,这个对象中一定会有一些固有的方法比如在es6中的promise内部就存在then,catch等方法。

    2.存在三种状态,未完成状态、已完成状态、出错状态(失败)。

    3.对于现在的promise就是使用then来进行promise内部成功的代码,catch用来捕获发生的错误。

    var msg = "";
    var msg1 = ""; 
    getJSON(url){
          var promise = new Promise((resolve, reject) => {
            var client = new XMLHttpRequest();
            client.open("GET", url,true);
            client.onreadystatechange = handler;
            client.send(null);
    
            function handler() {
              if(this.readyState==4){
                if (this.status === 200) {
                  resolve(this.responseText);
                } else {
                  reject(new Error(this.statusText));
                }
              }
              
            };
          });
          return promise;
        }
        ineer(){
          getJSON("src/1.txt").then((json) => {
            msg=json;
            msg1=json;
          }).then(() => {
            this.getJSON("src/2.txt");
          }).then((json1) => {msg1 = json1+msg1;})

        .catch((error) => { console.error('出错了', error); }); } inner();

    以上是使用promise规范来写一个ajax异步提取文本数据的代码。

    8.HTTP状态码

    http状态码是比较多的。全部的可以直接百度。我记下的其实也不是很多。

    比如最基本的200是代表成功。404代码代表服务器无法找到资源。408请求超时。400请求有错误。

    另外还可以大范围记一些。不需要知道到底在哪里出错了。但是大致错误知道。例如

    1打头的三位数状态码。代表请求已经被接受,需要继续操作。

    2打头的三位数状态码。代表请求已经成功被服务器接受,理解。

    3打头的三位数状态码。代表客户端需要采取进一步操作才能完成请求。大多用来重定向中。

    4打头的三位数状态码,代表出现错误了。

    5、6打头的三位数状态码,代表服务器发生了错误。

    9.HTTP首部有哪些关于缓存的字段

    关于http首部的字段还是比较多的,除了请求头之外,还存在响应头部。虽然我知道的也不是很多,所以就直接上网查询了一下所有的,在此记录一下。

    请求头:浏览器向服务器发送请求的数据,资源。

    响应头:服务器向浏览器响应数据,告诉浏览器我是谁,我要你做什么。

    常见的请求头:
    Accept: text/html,image/*                                            浏览器可以接收的类型 
    Accept-Charset: ISO-8859-1                                      浏览器可以接收的编码类型
    Accept-Encoding: gzip,compress                               浏览器可以接收压缩编码类型 
    Accept-Language: en-us,zh-cn                                浏览器可以接收的语言和国家类型
    Host: www.lks.cn:80                                               浏览器请求的主机和端口
    If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT   某个页面缓存时间 
    Referer: http://www.lks.cn/index.html                         请求来自于哪个页面
    User-Agent: Mozilla/4.0 compatible; MSIE 5.5; Windows NT 5.0   浏览器相关信息
    Cookie:                                                                    浏览器暂存服务器发送的信息
    Connection: close1.0/Keep-Alive1.1                          HTTP请求的版本的特点
    Date: Tue, 11 Jul 2000 18:23:51GMT                       请求网站的时间
    Allow:GET                                                                  请求的方法 GET 常见的还有POST
    Keep-Alive:5                                                            连接的时间;5
    Connection:keep-alive                                             是否是长连接
    Cache-Control:max-age=300                                   缓存的最长时间 300s
     
    常见的响应头:
    Location: http://www.lks.cn/index.html                          控制浏览器显示哪个页面 
    Server:apache nginx                                                   服务器的类型 
    Content-Encoding: gzip                                               服务器发送的压缩编码方式 
    Content-Length: 80                                                     服务器发送显示的字节码长度 
    Content-Language: zh-cn                                           服务器发送内容的语言和国家名 
    Content-Type: image/jpeg; charset=UTF-8                 服务器发送内容的类型和编码类型 
    Last-Modified: Tue, 11 Jul 2000 18:23:51GMT           服务器最后一次修改的时间 
    Refresh: 1;url=http://www.lks.cn                                  控制浏览器1秒钟后转发URL所指向的页面 
    Content-Disposition: attachment; filename=lks.jpg      服务器控制浏览器发下载方式打开文件 
    Transfer-Encoding: chunked                                      服务器分块传递数据到客户端  
    Set-Cookie:SS=Q0=5Lb_nQ; path=/search                服务器发送Cookie相关的信息 
    Expires: -1                                                                  资源的过期时间,提供给浏览器缓存数据,-1永远过期 
    Cache-Control: no-cache                                           告诉浏览器,一定要回服务器校验,不管有没有缓存数据。 
    Pragma: no-cache                                                      服务器控制浏览器不要缓存网页   
    Connection: close/Keep-AliveHTTP                           请求的版本的特点   
    Date: Tue, 11 Jul 2000 18:23:51 GMT                       响应网站的时间 
    ETag:“ihfdgkdgnp98hdfg”                                       资源实体的标识(唯一标识,类似md5值,文件有修改md5就不一样)

     以上就是http的头部信息。其中具有关于缓存的大概是:

    Expires:一个GMT时间,告诉浏览器,在此时间内,可以信任并且使用对应的缓存数据。但是一般会获取客户端的时间,可能会导致错误。

    Pragma:服务端控制浏览器不要缓存。

    Cache-Control:

    更加详细的可以查看http://blog.csdn.net/zhsh87/article/details/8186753

    10.服务器怎么判断304

    HTTP 304:Not Modified 请求后读取本地缓存的文件。

    解释:客户端有缓存的文档并发出一个条件性的请求。服务器告诉客户端,原来的缓冲的文件可以继续使用。

    大致的浏览器工作原理:

    1.在我们使用浏览器的时候很多时候会在缓存中直接获取内容。比如。前一页、后一页等浏览器操作,不会事浏览器在expires和max-age过期时间之内访问浏览器,而是直接去缓存中去获取内容。(expires和max-age是用来记录文件是否缓存过期的请求头部信息)

    2.访问服务器,根据服务器响应来获取内容。当然需要结合相应的头部信息来一起起作用。例如no-cache的时候因为不缓存,Last-Modified、Etag、must-revalited有些特殊,不直接受浏览器行为影响,它们必须访问服务器之后,再由服务器判断是直接发送新的资源,还是使用304让浏览器使用缓存中的资源。

    304大致情况如下:

    客户端在请求文件的时候,如果自己已经缓存的文件中有last modified,那么就会在请求中添加If Modified Since,这个就是一个时间,和last modified相同。故而如果在相应的后端接收到请求的时候,判断If Modified Since与请求的文件在服务端的修改时间就可以最后确定返回的是304,又或者是200。对于css、图片,服务器会自动完成比较。但是对于动态网页则有一些问题,动态产生的页面,大多没有last modified信息,这样浏览器就不会缓存,所以每次都是200。

    二面

    1.进程与线程的区别

    1.进程是资源分配的最小单位,线程是程序执行的最小单位。

    2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程小很多。

    3.线程之间的通信更方便,同一线程下得进程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。

    4.但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

    2.SQL中事务的概念

    事物实际上就是一种机制的存在,例如我们需要操作数据库,有一系列的命令操作,那么这组命令实际上就是就是一个事务,另外这组命令要不都不执行,要么就都执行一遍。

    事务属性:

    1.原子性:事务是一个完整的操作。

    2.一致性:当事务完成的时候,数据必须处于一致状态。

    3.隔离性:对数据进行修改的所有并发事务是彼此隔离的。

    4.持久性:事务完成以后,它对系统的影响是永久的。

    3.死锁

    死锁实际上就是假设俩个进程a1和a2都需要使用B1和B2俩个资源。a1持有B1后等待B2,而a2正好持有B2等待B1,俩者都不想放弃手中的现有资源,这就出现了死锁。

    当然还要明确计算机哪些资源是可以抢占的、有些事不可以抢占的。

    可抢占:主存、cpu等可共享的资源。

    不可抢占:打印机,光驱等不可共享的资源。

    4.产生死锁的条件

    好像上面已经答了。。。

    还有一些比较详细的:

    1.互斥条件:某个资源只能被一个进程使用,其他的进程请求该资源时候,只能等待,直到资源使用完毕后释放该资源。

    2.请求和保持条件:进程已经保持了至少一个资源,但是又提出了新的要求,而这个资源被其他进程占用,自己占用的资源却不放。

    3.不可抢占条件:进程已经获得的资源没有使用完,不能被抢占。

    4.循环等待条件:必然存在一个循环链

    5.CHAR和VARCHAR的区别

    首先要知道这俩者都是数据库的存储数据类型,并且都是字符串类型的数据类型。

    区别在于,如果我们规定该列数据的类型为char且长度为10,那么如果我们输入'abcd',这时的字符串实际上是4的长度。那么它在数据库中依旧按照10的长度存储,会有6的浪费。

    而varchar不会有这样的问题,假如上面的条件都不改变,仅改变数据的类型,那么实际上它占有的长度就是字符串的长度4。这样就达到了节省资源的目的。

    但是!char的存取速度是要比varchar快很多的。因为长度固定,方便程序的存储和查找,但是char也付出了空间的浪费的代价。

    并且还有一个区别就是char对于每一个英文字符占用1个字节,汉字占用俩个字节。varchar都是占用2个字节。

    8.前端安全

    ok。这又回到xss攻击和csrf攻击模式上面了。

    这回再说一遍我的理解吧。

    首先说一下xss攻击是指什么,在我的理解里面,实际上它就是一种html注入式攻击,简单来说,如果我们使用的是一个类似csdn或者博客园这种,我们如果加上<script>alert(aaa)</script>,那么实际上显示的时候可能会弹出一个对话框,那么如果我们更深一步,在script特定标签内部使用某种特殊的带有危害性性质的东西,例如发送cookie或者一些其他的问题,就会导致不安全的事件发生。解决起来其实不是特别麻烦,我们需要对用户的输入进行一些详细的限制例如将<>都转化为实体字符的形式存在。

    第二个就是csrf上面了,同样在我的理解里面他是一种可以盗取用户的cookie的并假借用户的名义进行一次请求的发送。我们在一些特殊的网页,例如银行等等,我们需要使用cookie等记录登录状态,假如我们此时再打开一个危险的网页,这时候这个危险网页可能会读取另一个特殊的网页内部的cookie并模拟发送请求,这样就会有安全问题的产生了。解决办法就是可以验证http头部带有的一个特殊的Referer来验证是否这个请求是规范的自己的请求,当然这个也是可以模拟的,除此之外还可以使用验证码的形式。

    10.重定向怎么实现

    redirect。node带有一个请求的返回response.redirect()。

    11.离开确认怎么实现

    onbeforeunload js自带的验证是否离开

    12.并行和并发

    并行可以解释为:假设俩组排队的人都要打咖啡,每组都有自己的咖啡机,俩组人互不干扰。

    并发可以解释为:假设俩组排队的人都要打咖啡,但是只有一个咖啡机,俩组人需要进行竞争。

    所以说,并发意味着多个执行的实体需要竞争资源,不可避免产生竞争和同步的关系。而并行则是不同的执行实体拥有各自的资源,相互之间互不干扰。

    美团

    一面

    1.Vue双向数据绑定
    2.diff算法
    3.vue计算属性如何实现
    4.vdom优缺点
    5.SPA原理
    6.webpack用过那些loader
    7.gitHub
    8.angular脏检查
    9.export看代码说结果(好像babel转码的export和node里的不太一样)
    10.let、const
    11.箭头函数
    12.localStorage缺点
    13.手写算法,求二叉树中两个标记的节点之间的最短路径吧,(类似迪杰特斯拉算法吧)

    二面

    1.无序数组,找出所有满足条件的数,这个数比前面的数都大,比后面的数都小
    2.js继承
    3.实现一个简单的mvvm
    4.实现一个装饰者模式
    5.看过哪些书
    6.this绑定
    7.HTTP缓存,ETag

    三面

    1.prototype属性
    2.跨域安全,怎么防范
    3.设计方面的书
    4.UI的了解
    5.CSS的书
    6.前端哪里不好
    7.问了一些复杂的设计模式
    8.项目亮点
    9.MVC

  • 相关阅读:
    【BZOJ】1710: [Usaco2007 Open]Cheappal 廉价回文
    【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站
    【BZOJ】1706: [usaco2007 Nov]relays 奶牛接力跑
    【Atcoder】CODE FESTIVAL 2017 qual A D
    【BZOJ】3038: 上帝造题的七分钟2 && 3211: 花神游历各国
    【BZOJ】1707: [Usaco2007 Nov]tanning分配防晒霜
    【BZOJ】1754: [Usaco2005 qua]Bull Math
    【BZOJ】1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
    【BZOJ】1828: [Usaco2010 Mar]balloc 农场分配(经典贪心)
    【BZOJ】1709: [Usaco2007 Oct]Super Paintball超级弹珠
  • 原文地址:https://www.cnblogs.com/acefeng/p/8573207.html
Copyright © 2020-2023  润新知