web前端常见面试题

假装没事ソ 提交于 2020-12-10 06:42:21

1、什么是盒子模型?

CSS 盒模型(Box Model),又称框模型。它包括:content、padding、border、margin,所有HTML元素都可以看作盒子。

注: 当通过CSS指定一个元素的宽度和高度属性时,只是设置了实际内容区域的宽度和高度。

一旦为页面设置了恰当的 DTD,浏览器会使用标准盒模型(标准模式),而DTD缺失则在ie6,ie7,ie8下将会使用IE盒模型(怪异模式)。

标准盒模型 元素总宽度 = width + (padding + border + margin)* 2

IE盒模型   元素总宽度 = width + margin * 2

 

2、行内元素有哪些?块级元素有哪些? 空(void)元素有那些?

行内元素:a、b、span、img、input、strong、select、label、em、button、textarea
块级元素:div、form、ul、li、dl、dt、dd、p、h1-h6、blockquote
空元素:即系没有内容的HTML元素,例如: meta、link 、br、hr、input、img

 

3、CSS实现垂直水平居中

方法一:

给元素设置一个显示宽度,并设置左右margin为auto

方法二:

父元素设置相对定位

position: relative;

子元素设置绝对定位,并设置top、left、margin-top、margin-left等属性

       position: absolute;

       top: 50%;

       left: 50%

       margin-top: -(高度 / 2)

       margin-left: -(宽度 / 2)

方法三:

父元素设置相对定位

position: relative;

子元素设置绝对定位,并设置top、left、margin-top、margin-left等属性

       position: absolute;

       top: 50%;

       left: 50%

       transform: translate(-50%, -50%);      // translate的参数会以自身的长宽做参考

方法四:

内联元素水平居中

利用 text-align: center; 可以实现在块级元素内部的内联元素水平居中。此方法对内联元素(inline), 内联块(inline-block), 内联表(inline-table), inline-flex元素水平居中都有效。

 

4、简述一下src与href的区别

href (Hypertext Reference) 超文本引用,用在link和a等元素上,指向网络资源所在位置,建立与当前元素或当前文档之间的超链接。

src指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。  

补充:link和@import的区别

两者都是外部引用CSS的方式,但是存在一定的区别。

区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。

区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。

区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。

区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。

 

5、什么是CSS Hack?

一般来说是针对不同的浏览器写不同的CSS,就是 CSS Hack。
IE浏览器Hack一般又分为三种,条件Hack、属性级Hack、选择符Hack(详细参考CSS文档:css文档)。例如:

    // 1、条件Hack
   <!--[if IE]>
      <style>
            .test{color:red;}
      </style>
   <![endif]-->
   // 2、属性Hack
    .test{
    color:#090\9; /* For IE8+ */
    *color:#f00;  /* For IE7 and earlier */
    _color:#ff0;  /* For IE6 and earlier */
    }
   // 3、选择符Hack
    * html .test{color:#090;}       /* For IE6 and earlier */
    * + html .test{color:#ff0;}     /* For IE7 */

6、简述同步和异步的区别

同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。


7、px和em的区别

px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。

em的值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em


8、什么叫优雅降级和渐进增强?

渐进增强 progressive enhancement:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

区别:

a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

 

9、浏览器的内核分别是什么?

IE: trident内核
Firefox:gecko内核
Safari:webkit内核
Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核
Chrome:Blink(基于webkit,Google与Opera Software共同开发)

 

10、怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点

2)添加、移除、替换、插入
parentnode.appendChild(newnode) //添加
parentnode.removeChild(oldnode) //移除
parentnode.replaceChild(newnode, oldnode) //替换
parentnode.insertBefore(newnode, oldnode) //插入

3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性

 

11、如何消除一个数组里面重复的元素?

方法一:

var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];

    for (var i = 0, len = arr1.length; i < len; i++ ) {

        if (arr2.indexOf(arr1[i]) < 0) {

            arr2.push(arr1[i]);

        }

}

console.log(arr2);

 

    var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];

    arr1.forEach(function (item, index) {

        if (arr2.indexOf(item) < 0) {

            arr2.push(item);

        }

})

console.log(arr2);

方法二:

var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];

    arr1.sort(function (a, b) {

        return a - b;

    })

    for (var i = 0, len = arr1.length; i < len; i++) {

        if (arr1[i] != arr1[i + 1]) {

            arr2.push(arr1[i]);

        }

    }

    console.log(arr2);

 

12、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制。

typeof能返回六种数据类型,undefined、number、string、boolean、object、function

    function clone(obj) {

        var o;

        switch(typeof obj) {

            case "undefined":

                break;

            case "string":

                o = obj;

                break;

            case "number":

                o = obj;

                break;

            case "boolean":

                o = obj;

                break;

            case "object":

                if (obj === null) {

                    o = null;

                } else if (obj.constructor === Array) {

                    o = [];

                    obj.forEach(function (item, index) {

                        o[index] = clone(item);

                    })

                } else {

                    o = {};

                    for (var key in obj) {

                        o[key] = clone(obj[key]);

                    }

                }

                break;

            default:

                o = obj;

                break;

        }

        return o;

    }

 

13、javascript中的call、apply、bind

参考:https://www.cnblogs.com/coco1s/p/4833199.html

apply 、 call 、bind 三者都是用来改变函数的this对象的指向;

apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

apply 、 call 、bind 三者都可以利用后续参数传参;

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

 

14、在Javascript中什么是伪数组?如何将伪数组转化为标准数组?

伪数组(类数组):拥有length属性但不具有数组所具有的方法。典型的是函数的arguments参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。

function log(){

//为了使用unshift数组方法,需将arguments转化为真正的数组

        var args = Array.prototype.slice.call(arguments); 

 

        args.unshift('(app)');

        console.log.apply(console, args);

    };

 

15、Javascript中callee和caller的作用?

参考:https://www.cnblogs.com/niulina/p/5701404.html

callee是arguments对象的属性,指向拥有这个arguments对象的函数。(递归调用)

caller是函数对象的属性,这个属性保存着调用当前函数的函数的引用。

 

16、请描述一下cookies,sessionStorage和localStorage的区别

参考:https://segmentfault.com/a/1190000012057010

webstorage,包括localStorage和sessionStorage,是本地存储,存储在客户端浏览器中。

localStorage生命周期是永久,除非用户主动的在浏览器上清除localStorage信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。

sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。

localStorage和sessionStorage使用相同的API:

localStorage.setItem("key","value");//以“key”为名称存储一个值“value”

localStorage.getItem("key");//获取名称为“key”的值

localStorage.removeItem("key");//删除名称为“key”的信息。

localStorage.clear();​//清空localStorage中所有信息

cookie的生命期在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。 存放数据大小为4K左右 。有个数限制(各浏览器不同),一般不能超过20个。与服务器端通信:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题。但Cookie需要程序员自己封装,源生的Cookie接口不友好。

localStorage、sessionStorage、Cookie共同点:都是保存在浏览器端,且同源的。

Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生。

 

17、统计字符串中字母个数或统计最多字母数。

var str = "aaaabbbccccddfgh";

    var obj = {};

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

        if (obj[str[i]] == undefined) {

            obj[str[i]] = 1;

        } else {

            obj[str[i]]++;

        }

    }

    for (var key in obj) {

        console.log(key + " = " + obj[key]);

    }

 

    var arr = Object.values(obj);

    var max = Math.max.apply(null, arr);

    var letterMaxNum = Object.keys(obj)[arr.indexOf(max)];

    console.log("出现次数最多的字母:" + letterMaxNum);

 

18、一次完整的HTTP事务是怎样的一个过程?

基本流程:

a. 域名解析

b. 发起TCP的3次握手

c. 建立TCP连接后发起http请求

d. 服务器端响应http请求,浏览器得到html代码

e. 浏览器解析html代码,并请求html代码中的资源

f. 浏览器对页面进行渲染呈现给用户

 

19、HTTP的状态码有哪些?

HTTP状态码共分为5种类型:

1**          信息,服务器收到请求,需要请求者继续执行操作

2**          成功,操作被成功接收并处理

3**          重定向,需要进一步的操作以完成请求

4**          客户端错误,请求包含语法错误或无法完成请求

5**          服务器错误,服务器在处理请求的过程中发生了错误

常用的状态码:

200         请求成功。

301         永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302         临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

304         未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

400         客户端请求的语法错误,服务器无法理解

401         请求要求用户的身份认证

403         服务器理解请求客户端的请求,但是拒绝执行此请求

404         服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

500         服务器内部错误,无法完成请求

 

20、HTTPS是如何实现加密?

HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL (安全套接字层)和TLS (安全传输层协议)代替而已。即添加了加密及认证机制的 HTTP 称为 HTTPS ( HTTP Secure )。

HTTP + 加密 + 认证 + 完整性保护 = HTTPS

公开密钥加密使用一对非对称的密钥。一把叫做私钥,另一把叫做公钥。私钥不能让其他任何人知道,而公钥则可以随意发布,任何人都可以获得。使用公钥加密方式,发送密文的一方使用对方的公钥进行加密处理,对方收到被加密的信息后,再使用自己的私钥进行解密。利用这种方式,不需要发送用来解密的私钥,也不必担心密钥被攻击者窃听而盗走。

 

21、手写数组快速排序

参考:http://www.ruanyifeng.com/blog/2011/04/quicksort_in_javascript.html

"快速排序"的思想很简单,整个排序过程只需要三步:
(1)在数据集之中,选择一个元素作为"基准"(pivot)。
(2)所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
(3)对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

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 = [];

        arr.forEach(function(item, index) {

            if (item < pivot) {

                left.push(item);

            } else {

                right.push(item);

            }

        })

        return quickSort(left).concat(pivot, quickSort(right));

    }

    var arr = [11, 1, 24, 100, -1, 45, 0];

quickSort(arr);

 

22、JavaScript实现二分法查找

二分法查找,也称折半查找,是一种在有序数组中查找特定元素的搜索算法。查找过程可以分为以下步骤:
(1)首先,从有序数组的中间的元素开始搜索,如果该元素正好是目标元素(即要查找的元素),则搜索过程结束,否则进行下一步。
(2)如果目标元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半区域查找,然后重复第一步的操作。
(3)如果某一步数组为空,则表示找不到目标元素。

// 非递归算法

    function binary_search(arr, key) {

        var low = 0;

        var high = arr.length - 1;

        while(low <= high) {

            var mid = Math.floor((low + high) / 2);

            if (key == arr[mid]) {

                return mid;

            } else if (key < arr[mid]) {

                high = mid - 1;

            } else if (key > arr[mid]) {

                low = mid + 1;

            } else {

                return -1;

            }

        }

        return -1;

    }

    var arr = [1, 22, 25, 30, 45, 100];

    binary_search(arr, 10);

 

    // 递归算法

    function binary_search(arr, key, low, high) {

        if (low > high) {

            return -1;

        }

        var mid = Math.floor((low + high) / 2);

        if (key == arr[mid]) {

            return mid;

        } else if (key < arr[mid]) {

            high = mid - 1;

            return binary_search(arr, key, low, high);

        } else if (key > arr[mid]) {

            low = mid + 1;

            return binary_search(arr, key, low, high);

        } else {

            return -1;

        }

    }

    var arr = [1, 22, 25, 30, 45, 100];

    binary_search(arr, 100, 0, arr.length - 1);

 

作者:GeniusLyzh
出处:http://www.cnblogs.com/GeniusLyzh/
本文链接:https://www.cnblogs.com/GeniusLyzh/p/5272902.html
本文版权归作者和博客园共有,欢迎转载,须保留此段声明,并给出原文链接,谢谢!
如果阅读了本文章,觉得有帮助,欢迎点击右下角推荐

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!