美文网首页
前端面试总结

前端面试总结

作者: 足够幸运 | 来源:发表于2019-03-19 11:37 被阅读0次

1.不包含掘金小册

掘金小册的内容就不在这总结了,下边的内容是其他一些小细节,面试分为笔试和口头面对面交流。本大纲只是自己总结的注意的点,有的具体知识还需要自己去查相关资料深入学习。这只是适合本人的平时阅读和注意的小册。
注重基础知识,算法基础(数组降维,去重,排序),html布局,css选择器,http(状态码),缓存及更新问题,,服务器端知识。

2.清除浮动的方式(介绍几种就行,几乎全部了,O(∩_∩)O哈哈~)

(1)父级div定义height。

(2)结尾处加空div标签clear:both。

(3)父级div定义伪类:after和zoom(兼容ie6,7,推荐使用)。

(4)父级div定义overflow:hidden。

(5)父级div定义overflow:auto。

(6)父级div也浮动,需要定义宽度。

(7)父级div定义display:table。

(8)结尾处加br标签clear:both。

3.Html5新特性

 (1)绘画 canvas;

 (2)用于媒介回放的 video 和 audio 元素;

 (3)本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;

 (4)sessionStorage 的数据在浏览器关闭后自动删除;

 (5)语意化更好的内容元素,比如 article、footer、header、nav、section;

 (6)表单控件,calendar、date、time、email、url、search;

4.Js数据类型相关

 (1)原始类型有哪几种?null 是对象嘛?

    原始类型:boolean,null,undefined,number,string,symbol

     typeof null 结果为 object,即typeof null === ‘object’typeof返回字符串

  (2)对象类型

    在JS 中,除了原始类型那么其他的都是对象类型了。对象类型和原始类型不同的是,原始类型存储的是值,对象类型存储的是地址(指针)。当你创建了一个对象类型的时候,计算机会在内存中帮我们开辟一个空间来存放值,但是我们需要找到这个空间,这个空间会拥有一个地址(指针)。

    这句话很重要,解答题的关键就是创建一个对象类型的时候,重新分配一个地址(指针)

  (3)typeof和instanceof

    typeof对于原始类型来说,当然除了null都可以显示正确的类型,eg:typeof ‘1’//’string’
    typeof 对于对象类型来说,除了函数都会显示 object,所以说typeof 并不能准确判断变量到底是什么类型 eg:typeof console.log //’function’。

    instanceof 用于判断一个变量是否某个对象的实例。

  (4)类型转换

    具体看掘金小册,多做一些类型装换的题,把概念练熟了。

    加法运算:

    自己的概括为,(1)如果有对象类型,先转化为基本数据类型(就是转化为字符串,eg:{}=>’[object,Object]’)第一个o小写,第二个大写。(2)有字符串就会都转为字符串,(3),其他情况都转换为数字运算

    其他运算:只要一方是数字,另一方也会转为数字,eg:

    4 * '3' // 12 

    4 * [] // 0

    4 * [1, 2] // NaN

   (5)null和undefined区别

    虽然都是原始类型。但是比如null==undefined返回true,null===undefined,返回false,因为类型不一样,

    null:typeof null是‘object’,转为数字为0。

    Undefined:typeof undefined是undefined,转为数字为NaN。

5.This指向

 优先级从上到下

(1)new方式,this指向new的对象。

(2)bind,apply,call这些绑定函数的第一个参数

(3)Obj.foo(),this指向Obj对象

(4)function foo(),普通函数this指向window,

(5)箭头函数的this,一旦被绑定,不会再被改变

6. Call,apply,bind

    都是改变函数调用中this的指向的

    call和apply: 临时借用构造函数,并临时替换函数中的this为指定对象。 立刻执行函数调用后,this回复原样.
    call和apply接受两个参数,第一个参数是要绑定给this的值,第二个函数需要的参数。当第一个参数为null、undefined的时候,默认指向window。

    call: 参数单独传入

    apply: 参数以数组传入

    bind: 创建一个函数,并永久绑定this,不会立刻执行新函数,一旦被bind创建的函数,其中的this,无法再被call/apply替换

7.React内容

    react描述:声明式的(自己描述自己想要的东西,让react自己决定怎么做,如何做,开发人员不需要关心这个),组件化(组件化最重要的目的就是达到可重用),用于构建UI的一个js框架。

    React特点:

    1.声明式设计:用于描述应用

    2.高效:采用虚拟DOM结构,减少DOM操作(内部采用diff算法来检查更新DOM)

    3.灵活:可以结合很多框架

    4.jsx:js语法的扩展

    5.组件:可以组件重用,构建大型应用

    6.单项数据流:数据流是从上到下的数据流,可以搭配redux使用

    Redux描述:适用于,多交互,多数据源的应用,web应用是一个状态对应一个视图,它是将所有的状态都保存在一个对象里边,然后向下传递。

8. React和vue的区别

相似之处:
(1)使用 Virtual DOM;
(2)提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件;
(3)将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。
区别(自己总结,vue官网有相关介绍):
(1)在 React 应用中,当某个组件的状态发生变化时,它会以该组件为根,重新渲染整个组件子树。如要避免不必要的子组件的重渲染,你需要在所有可能的地方使用 PureComponent,或是手动实现 shouldComponentUpdate 方法。在 Vue 应用中,组件的依赖是在渲染过程中自动追踪的,所以系统能精确知晓哪个组件确实需要被重渲染。你可以理解为每一个组件都已经自动获得了 shouldComponentUpdate,并且没有上述的子树问题限制。
(2)Html和css方面:react采用jsx语法,vue采用模板语法。React采用引入css文件来渲染样式,vue直接在一个文件里写样式和html模板来描述组件
(3)状态管理:react:redux,vue:vuex
(4)原生渲染,跨平台:react 对应react native vue对应weex

9.解决问题的方法(每个人都应该有一个通用的思路,这很重要)

  (1)收集足够信息描述出问题,比如说发现一个bug,不知道问题出在哪,这就是没有收集到足够的信息导致的,你可以通过在搜索引擎搜索关键字的方式,查询相关的解决方案,不断的搜索收集足够多的信息,
  (2)学会问问题,要达到三点,1.问题发生的场景是什么,2.收集到相关的问题描述有哪些,3.希望问题解决后达到的效果是什么。
  (3)努力创造问题的重现环境,这样可以更快的发现问题的关键
  (4)不制造新问题。

10. Websocket

它是http5提供的一种客户端和服务器端双向的通讯的协议,和轮询不同,允许服务器主动发送信息给客户端

11.轮询

轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

12. Less和sass

13.React native了解一下

14. Dependencies和devDependencies区别

(1)devDependencies用于本地环境开发时候
(2) Dependencies用于生产环境(发布的时候

devDependencies是只会在开发环境下依赖的模块,生产环境不会被打入包内。通过NODE_ENV=developement或NODE_ENV=production指定开发还是生产环境。而dependencies依赖的包不仅开发环境能使用,生产环境也能使用。其实这句话是重点,按照这个观念很容易决定安装模块时是使用--save还是--save-dev。、

15. npm常用命令

    -4048报错:npm cache clean --force,清除缓存
    Npm install 安装依赖
    Npm uptate 更新
    Npm uninstall 卸载依赖
    Npm list -g 查看全局安装的包,也可以查看单独的
    Npm version patch 升级补丁号 即 0.1.0->0.1.1,主版本:major,次版本:minor。
    Npm publish 发布npm包

16.flex布局-掘金

17.原型和原型链

原型:
举个例子吧,比如创建一个对象,控制台打印,发现里边不只对象的属性还有proto属性,他就是原型对象,查看里边还有constructor 属性,也就是构造函数,打开 constructor 属性我们又可以发现其中还有一个 prototype 属性,并且这个属性对应的值和先前我们在 proto 中看到的一模一样。所以我们又可以得出一个结论:原型的 constructor 属性指向构造函数,构造函数又通过 prototype 属性指回原型。
原型链:
对象的 proto 属性指向原型, proto 将对象和原型连接起来组成了原型链

18. 闭包

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

在js中,闭包存在意义就是让我们能够访问到函数内部的变量。

发现的衍生题:如何创建js私有变量?


function func() {

      var priv = "secret code";

      return function() {

            return priv;

      }

}

var getPriv = func();

console.log(getPriv()); // => secret code

闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。

function A() {
  let a = 1
  window.B = function () {
      console.log(a)
  }
}
A()
B() // 1

19. Reduce()函数(连接)

 arr.reduce(function (x, y) {

     return x + y;

 });
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
total:必需。初始值, 或者计算结束后的返回值。
currentValue    必需。当前元素
currentIndex    可选。当前元素的索引
arr 可选。当前元素所属的数组对象。
initialValue    可选。传递给函数的初始值

20. 数组去重

(1)利用filter和indexOf


r = arr.filter(function (element, index, self) {

      return self.indexOf(element) === index;

});

(2)普通函数


 Array.prototype.removeDup3 = function(){

        var result = [];

        var obj = {};

        for(var i = 0; i < this.length; i++){

            if(!obj[this[i]]){

                    result.push(this[i]);

                    obj[this[i]] = 1;

            }

        }

        return result;

}

var arr = [1,2,2,5,2,"测试","test","测试","test"];

console.log(arr.removeDup3());

21. 素数(质数)

含义:素数和质数是没有区别的。质数(又称素数),是指在大于1的自然数中,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数)。比1大但不是素数的数称为合数,1和0既非素数也非合数。用到的数学知识:只要小于或等于根号N的数(1除外)不能整除N,则N一定是素数

鄙视题:帅选出1到100中的素数。


function get_primes(arr){

    return arr.filter(function(y){

        if (y == 1) {

            return false;

        }

        for(var i=2;i<=Math.sqrt(y);i++){

            if (y%i == 0){

                return false;

            }

        }

        return true;

    });

}

--------------------- 或者将Math.sqrt(y)换成key(filter函数的索引)

22. 常用的排序算法(冒泡、快速等)

简单介绍下数组的排序函数sort()

sort():1.接受function(x,y){}函数作为参数,2.返回的结果还是原数组,修改原数组


arr.sort(function (a, b) {

 return a-b//从小到大,return b-a 从大到小

});

快速排序:

 var quickSort = function(arr) {

    if (arr.length <= 1) { return arr; }

    var pivotIndex = Math.floor(arr.length / 2);

    var pivot = arr.splice(pivotIndex, 1)[0];//非常关键,改变了原数组

    var left = [];

    var right = [];

    for (var i = 0; i < arr.length; i++){

        if (arr[i] < pivot) {

            left.push(arr[i]);

        } else {

            right.push(arr[i]);

        }

   }

return quickSort(left).concat([pivot], quickSort(right)); };

var arr1 = [1,4,65,21,2,222,111];

console.log(quickSort(arr1));

冒泡排序:外循环控制需要比较的元素,比如第一次排序后,最后一个元素就不需要比较了,内循环则负责两两元素比较,将元素放到正确位置上

function bubbleSort(arr){
    var len=arr.length;
    for(var i=len-1;i>0;i--){
        for(var j=0;j<i;j++){
            if(arr[j]<arr[j+1]){
                var tmp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=tmp
            }
        }
    }
    return arr;
}

插入排序:
算法描述:
1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
4. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置
5. 将新元素插入到该位置后
6. 重复步骤 2~5
编程思路:双层循环,外循环控制未排序的元素,内循环控制已排序的 元素,将未排序元素设为标杆,与已排序的元素进行比较,小于则交换位置,大于则位置不动

 function insertSort(arr){
    var tmp;
    for(let i=1;i<arr.length;i++){
        tmp  = arr[i];
        //第二层循环,是遍历已排序的元素,并且是从后向前遍历
        for(let j=i;j>=0;j--){
            //如果已排序的元素大于未排序的则,已排序的元素向后移一位
            // if(arr[j-1]==undefined){
            //     console.log(j);
            // }
            if(arr[j-1]>tmp){
                //向后移一位
                arr[j]=arr[j-1];
            //否则(这里包括两种情况,第一种就是小于,第二种情况就是,当arr[j-1]==undefined,即当j=0的时候,也会走这个)    
            }else{
                arr[j]=tmp;
                break;
            }
        }
    }
    return arr
}

选择排序:把每一个数都与第一个数比较,如果小于第一个数,就把它们交换位置;这样一轮下来,最小的数就排到了最前面;重复n-1轮,就实现了选择排序,选择排序和冒泡排序思想上有些相近

 function selectSort(arr){
    var len=arr.length;
    var temp;
    for(var i=0;i<len-1;i++){
        for(var j=i+1;j<len;j++){
            if(arr[j]<arr[i]){
                temp=arr[j];
                arr[j]=arr[i];
                arr[i]=temp;
            }
        }
    }
    return arr;
}

23. property和attribute的区别

为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点.

attribute 是 dom 元素在文档中作为 html 标签拥有的属性;
property 是 dom 元素在 js 中作为对象拥有的属性。

从定义上可以看出:

对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的
但是对于自定义的属性来说,他们是不同步的.(自定义属性不会自动添加到property)
property 的值可以改变;attribute 的值不能改变

24. 事件相关

事件捕获或者冒泡,由element.addEventListener(event, function, useCapture)第三个参数决定,默认false,冒泡,

25. Ajax和Fetch

Ajax:AJAX不是JavaScript的规范,它只是一个哥们“发明”的缩写:Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求。

代码:


var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象

request.onreadystatechange = function () { // 状态发生变化时,函数被回调

    if (request.readyState === 4) { // 成功完成

        // 判断响应结果:

        if (request.status === 200) {

            // 成功,通过responseText拿到响应的文本:

            return success(request.responseText);

        } else {

            // 失败,根据响应码判断失败原因:

            return fail(request.status);

        }

    } else {

        // HTTP请求还在继续...

    }

}

// 发送请求:

request.open('GET', '/api/categories',true);//第三个参数可以省略,默认是true,表示是否异步,即使用回调函数
//修改请求消息头部xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');post请求需要
request.send( null/data);//如果是post请求,字符串结构是‘name=lal&age=23’,POST请求需要把body部分以字符串或者FormData对象传进去 

Fetch:是运用了异步Promise的,和XHR(XMLHttpRequest)同样的功能,是XHR的替代方案

Fetch,问一下 fetch 如何解决跨域问题?如何取消 fetch 请求?能否监听 fetch 的上传进度?这样也相当于间接地问到了 Promise 的问题,是不是要比让人突兀地讲一讲 Promise 好一些?

注意的点:注意的点太多,自行点击链接查看。

26. 跨域

    产生原因:浏览器的同源策略导致。

    1. 在同源域名下架设一个代理服务器

    2. Jsonp

    3. CORS

27. Cookie,sessionstorage,localstorage的区别

sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。而localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。web storage和cookie的区别 Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。除此,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生。

28. 经常浏览的技术社区

  掘金,思否,CSDN,GitHub,博客园

29. 什么是IIFE(立即调用函数表达式)

在避免污染全局命名空间时经常使用这种模式,因为IIFE(与任何其他正常函数一样)内部的所有变量在其作用域之外都是不可见的。

30. 防抖和节流

1.https://www.cnblogs.com/walls/p/6399837.html;

2.https://juejin.im/post/5c87b54ce51d455f7943dddb

函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段。(简单解释一下)

防抖:就是在频繁的触发的情况下,一段指定时间后在,才执行代码一次,比如搜索,不断的输入问题,在输入完后一段时间,再检索输入内容;

节流:就是,一段时间内,js只执行一次,比如说: 用户点击提交按钮,有可能服务器返回数据较慢,在频繁点击的情况下,在一段时间内只请求一次

31.重绘和回流

重绘:指的是当页面中的元素不脱离文档流,而简单地进行样式的变化,比如修改颜色、背景等,浏览器重新绘制样式(不改变DOM结构的操作,比如:改变字体颜色,背景颜色)

回流:指的是处于文档流中DOM 的尺寸大小、位置或者某些属性发生变化时,导致浏览器重新渲染部分或全部文档的情况(改变DOM的操作,比如:改变宽高,改变位置)

重点:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。

那么,在工作中我们要如何避免大量使用重绘与回流呢?:

    1.避免频繁操作样式,可汇总后统一一次修改

    2.尽量使用 class 进行样式修改,而不是直接操作样式

    3.减少 DOM 的操作,可使用字符串一次性插入

32. 浏览器解析URL

    1.用户输入 URL 地址。

    2.对 URL 地址进行 DNS 域名解析。

    3.建立 TCP 连接(三次握手)。

    4.浏览器发起 HTTP 请求报文。

    5.服务器返回 HTTP 响应报文。

    6.关闭 TCP 连接(四次挥手)。

    7.浏览器解析文档资源并渲染页面。

33.DNS域名解析

    提供的服务是用于将主机名和域名转换为IP 地址的工作:

34.TCP三次握手和四次挥手

一直没想到怎么说这个问题(看见那些陌生的字符,就醉了_

什么是TCP 呢?TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。(能大致描述出来就行,其他一些为什么,以后再研究)
三次握手:建立连接阶段,第一,客户端发送SYN=1的连接请求信号,告诉服务器,我想和你通讯,第二,服务器收到客户端的请求连接之后,就会发送给客户端一个确认信息(ACK),告诉客户端,我收到了,然后向客户端发送请求SYN(synchronous)连接,第三,客户端收到服务器的确认信息和连接请求,然后就开始通信。
四次挥手:第一次:客户端发送断开连接请求FIN给服务器,然后等待服务器确认,第二次:服务器发送最后的信息并且确认(知道)(ACK)客户端要断开连接,:第三次,(客户端知道服务器收到了自己的断开连接请求),所以此时接受服务器发送的消息并处于等待断开连接,服务器发送完数据后,处于等待断开连接状态,然后发送FIN断开连接,第四次,客户端收到服务器的断开连接请求,就会发送确认ACK消息给服务器,然后客户端处于时间等待状态,经过2MSL时间后,客户端断开自身连接,处于close状态,服务器只要收到了客户端发出的确认,立即进入CLOSED状态

35. 浏览器渲染页面(有时间改成自己的话描述)

浏览器通过HTMLParser 根据深度遍历的原则把 HTML 解析成 DOM Tree。

浏览器通过CSSParser 将 CSS 解析成 CSS Rule Tree(CSSOM Tree)。

浏览器将JavaScript 通过 DOM API 或者 CSSOM API 将 JS 代码解析并应用到布局中,按要求呈现响应的结果。

根据DOM 树和 CSSOM 树来构造 render Tree(渲染树)。

layout:重排(也可以叫回流),当 render tree 中任一节点的几何尺寸发生改变,render tree 就会重新布局,重新来计算所有节点在屏幕的位置。

repaint:重绘,当 render tree 中任一元素样式属性(几何尺寸没改变)发生改变时,render tree 都会重新画,比如字体颜色,背景等变化。

paint:遍历 render tree,并调动硬件图形 API 来绘制每个节点。

36. 深拷贝

    深拷贝是会拷贝所有层级的属性

(1)递归


function deepClone(obj){

    let objClone = Array.isArray(obj)?[]:{};//很重要,不然会出现将数组复制成对象的形式

    if(obj && typeof obj==="object"){//‘object’一定要是字符串,首字母小写

        for(let key in obj){

            if(obj.hasOwnProperty(key)){

                //判断ojb子元素是否为对象,如果是,递归复制

                if(obj[key]&&typeof obj[key] ==="object"){

                    objClone[key] = deepClone(obj[key]);

                }else{

                    //如果不是,简单复制

                    objClone[key] = obj[key];

                }

            }

        }

    }

    return objClone;

}  

(2)json方式


  function deepClone(obj){

        let _obj = JSON.stringify(obj),

        objClone = JSON.parse(_obj);

        return objClone

}  

这种方式有局限性:

 (1)会忽略undefined
 (2)会忽略symbol
 (3)不能序列化函数
 (4)不能解决循环引用对象的问题

浅克隆
(1)Object.assign

let a = {
  age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1

(2)对象...解构

let a = {
  age: 1
}
let b = { ...a }
a.age = 2
console.log(b.age) // 1

(3)遍历对象

  function clone(obj){//浅克隆
        //创建空对象objClone
        var objClone={};
        //遍历obj中每个属性
        for(var key in obj){
          //向objClone中添加一个新属性,和obj中当前属性同名,并赋值为obj的当前属性值
          objClone[key]=obj[key];
        }//(遍历结束)
        return objClone;
  }

37. 正则相关

38. Git和svn的区别

   1. svn是集中式版本控制系统,git是分布式版本控制系统。 这句话相信不知道多少人都听过,究竟什么是集中式什么是分布式?很明显嘛,就字面意思啊,这么来说吧,svn就是所有人修改的都是服务器上的程序,如果有人修改了同样的部分,那就冲突了。所以呢,一般团队会约定,对于公共部分的程序,尽量标注出开发人员特有标识,又或者A从上添加,B从下添加。 
    2.git就是开发人员创建自己的分支,这个分支就相当于将源码copy一份在本机上,之后修改的都是本地的代码,可随时拉取服务器的代码进行同步,git可创建无数分支,开发人员只需将自己修改的代码提交就可以了,这样冲突的几率会小很多。
    3.svn是直接与服务器进行交互,git是将项目缓存在本地再推送到服务器。
    4.svn必须在联网的情况下工作,git可不联网开发。
    5.svn易冲突,git不易冲突。
    6.svn旨在项目管理,git旨在代码管理。
    7.svn适用于多项目并行开发,git适用于单项目开发。
    8.svn适用于企业内部,由项目经理协调多个项目统筹开发,git适用于通过网络多人开发同一项目。

39. 性能优化(用户体验)

(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩等、

(2) CDN(内容分发网络)解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。

(4) 当需要设置的样式很多时设置className而不是直接操作style。

(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。

(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。

 (7) 图片预加载,将样式表放在顶部,将脚本放在底部(放在底部的原因:然后当浏览器在解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始)。

(8)缓存AJAX

 (9)html结构扁平化,减少嵌套。Css选择器优化,

40. 优雅降级和渐进增强

优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效。

渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。

41. XSS和CSRF简述及预防措施

    XSS:Cross Site Script 跨站脚本攻击

    防XSS:(1)HttpOnly防止窃取cookie(2)用户的输入检查(3)服务端的输出检查

    CSRF:Cross Site Request Forgery 跨站网站请求伪造

    防CSRF:(1)验证码 (2)Referer Check (3)token验证

42.Css相关

    Css hack:

43. Js模块化简介

44. Webpack

只能简单介绍下,需要运用才知道里边的东西:

介绍:webpack是一个js应用程序(前端)的模块打包工具,大致流程呢就是,找到入口文件,然后递归寻找依赖的文件,构造出依赖关系图,用loader加载不同的模块,plugins插件扩展webpack的功能,最后输出一个文件。

Loader:loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。 loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用webpack 的打包能力,对它们进行处理。

本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

Plugins:loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

45. 职业规划

在前端技术上有一定深度理解的基础上,开始扩展后端技术,服务器、数据库,等,朝着架构师和项目经理方向发展。

46. 自我介绍

47. 谈薪资(对薪资的要求)

48. 有什么要问的

能否简单的评价一下我的不足

49.为什么跳槽

个人遇见了天花板,希望找个更好的发展机会,最主要的就是,在上家公司,在技术上没有提升的空间,为了更好的发展,当然一小部分原因是,没有相关加薪制度。随意选择重新找份工作。

50.复习结构图

image image

相关文章

网友评论

      本文标题:前端面试总结

      本文链接:https://www.haomeiwen.com/subject/plkgmqtx.html