欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

面试题总结

程序员文章站 2022-05-12 23:37:53
...

只是作为自己整理的面试题,题目有难的也有超基础的

html+css问题总结

1、右边宽度固定,左边自适应

第一种方法:

<style>
body{
    display: flex;
}
.left{
    background-color: rebeccapurple;
    height: 200px;
    flex: 1;
}
.right{
    background-color: red;
    height: 200px;
    width: 100px;
}
</style>
<body>
    <div class="left"></div>
    <div class="right"></div>
</body>
复制代码

第二种实现

<style>
    div {
        height: 200px;
    }
    .left {
        float: right;
        width: 200px;
        background-color: rebeccapurple;
    }
    .right {
        margin-right: 200px;
        background-color: red;
    }
</style>
<body>
    <div class="left"></div>
    <div class="right"></div>
</body>
复制代码

2、未知宽高垂直居中问题

方法一

思路:显示设置父元素为:table,子元素为:cell-table,这样就可以使用vertical-align: center,实现水平居中

优点:父元素(parent)可以动态的改变高度(table元素的特性)

缺点:IE8以下不支持

<style>
    .parent1{
        display: table;
        height:300px;
        width: 300px;
        background-color: #FD0C70;
    }
    .parent1 .child{
        display: table-cell;
        vertical-align: middle;
        text-align: center;
        color: #fff;
        font-size: 16px;
    }

</style>
<div class="parent1">
    <div class="child">hello world-1</div>
</div>
复制代码

方法二:

思路:使用一个空标签span设置他的vertical-align基准线为中间,并且让他为inline-block,宽度为0

缺点:多了一个没用的空标签,display:inline-block,IE6 7是不支持的(添加上:_zoom1;*display:inline)。 当然也可以使用伪元素来代替span标签,不过IE支持也不好,但这是后话了

<style>
    .parent2{
        height:300px;
        width: 300px;
        text-align: center;
        background: #FD0C70;
    }
    .parent2 span{
        display: inline-block;;
        width: 0;
        height: 100%;
        vertical-align: middle;
        zoom: 1;/*BFC*/
        *display: inline;
    }
    .parent2 .child{
        display: inline-block;
        color: #fff;
        zoom: 1;/*BFC*/
        *display: inline;
    }

</style>
<div class="parent2">
    <span></span>
    <div class="child">hello world-2</div>
</div>
复制代码

方法三

思路:子元素绝对定位,距离顶部 50%,左边50%,然后使用css3 transform:translate(-50%; -50%)

优点:高大上,可以在webkit内核的浏览器中使用

缺点:不支持IE9以下不支持transform属性

<style>
    .parent3{
        position: relative;
        height:300px;
        width: 300px;
        background: #FD0C70;
    }
    .parent3 .child{
        position: absolute;
        top: 50%;
        left: 50%;
        color: #fff;
        transform: translate(-50%, -50%);
    }
</style>
<div class="parent3">
    <div class="child">hello world-3</div>
</div>
复制代码

方法四:

思路:使用css3 flex布局

优点:简单 快捷

缺点:兼容不好吧,详情见:http://caniuse.com/#search=flex

<style>
    .parent4{
        display: flex;
        justify-content: center;
        align-items: center;
        width: 300px;
        height:300px;
        background: #FD0C70;
    }
    .parent4 .child{
        color:#fff;
    }
</style>
<div class="parent4">
    <div class="child">hello world-4</div>
</div>
复制代码

3、盒模型

获取页面元素位置与宽高:

element.clientWidth = content + padding

element.clientHeight = content + padding

javascript总结

1、let与var的区别?

let 为 ES6 新添加申明变量的命令,它类似于 var,但是有以下不同:

  1. var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
  2. let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
  3. let 不允许重复声明.

2、ajax请求的时候get和post方式的区别,用jQ写出ajax请求

GET请求:浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

POST请求:浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

$.ajax({
    url:url,
    data:data,
    success:success,
    dataType:dataType
});
复制代码

3、操作数组的方法都有哪些?

(pop、push、unshift、shift、splice、reverse、sort)、slice、indexOf、lastIndex、concat(数据的变异 括号中的能改变原数组)

forEach、filter、map(映射)、find、some、every、includes、reduce

4、数组去重

[...new Set([1,2,3,1,'a',1,'a'])];     //[1, 2, 3, "a"]
复制代码
var ary = [1,2,3,5,1,2],obj = {};
    for(var i = 0; i < ary.length; i++){
        var cur = ary[i];
        if(obj[cur] == cur){
            ary[i] = ary[ary.length - 1];
            ary.length -= 1;
            i--;
            continue;
        }
        obj[cur] = cur;
    }
    obj = null;
    console.log(ary);
复制代码

5、怎么判断两个对象相等?

obj={
    a:1,
    b:2
}
obj2={
    a:1,
    b:2
}
obj3={
    a:1,
    b:'2'
}
//转换为字符串进行判断
JSON.stringify(obj)==JSON.stringify(obj2);//true
JSON.stringify(obj)==JSON.stringify(obj3);//false
复制代码

6、请描述cookies、sessionStorage和localStorage的区别

特性 Cookie sessionStorage localStorage
数据的生命周期 一般由服务器生成,可以设置失效时间,如果在浏览器端生成Cookie,默认关闭浏览器后失效 仅在当前会话下有效,关闭页面或浏览器后被清除 除非被清除,否则永久保存
存放数据大小 4k左右 一般为5m 一般为5m
与服务器端通信 每次都会携带在HTTP头中,如果保存过多数据,会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

7、重排和重绘

  • 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算。这被称为重排。注意这里至少会有一次重排-初始化页面布局。
  • 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新。这样的更新被称为重绘。

什么情况会触发重排和重绘?

  • 添加、删除、更新 DOM 节点
  • 通过 display: none 隐藏一个 DOM 节点-触发重排和重绘
  • 通过 visibility: hidden 隐藏一个 DOM 节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的 DOM 节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

8、this指向问题

  1. 自执行函数中的this永远是window

定时器绑定方法中的this是window

在函数执行传递的回调函数中,一般情况下的this都是window,但是我们可以自己指定里面的this指向问题

//改变this关键字的bind方法
function bind(context,fn){
    var outerArg=Array.prototype.slice.call(arguments,2);
    return function(){
        var innerArg=Array.prototype.slice.call(arguments,0);
        var arg=outerArg.concat(innerArg);
        fn.apply(context,arg);
      }
}
复制代码
  1. 给元素的某一个事件绑定一个方法(DOM0、DOM2事件绑定),在事件触发执行对应方法的时候,方法中的this是当前元素 (在IE6~8中DOM2绑定事件中的this是window)
  2. 看方法执行前面是否有".",没有就是window,有的话,"."前面是谁this就是谁
  3. 在构造函数模式中,我们函数体中的this.xxx=xxx是给当前的实例增加私有的属性和方法呢,这里的this就是当前这个类的一个实例
  4. 使用call和apply强制改变this [非严格模式] 第一个参数不传/传递的是null或者undefined ->this都是window [严格模式] 第一个参数不传/undefined this->undefined 如果传递的是null this->null

9、标准事件模型 冒泡和捕获的过程

事件冒泡:从内到外

事件捕获:从外到内

addEventListener(event,false/true) true,事件捕获;false,事件冒泡。默认false -----attachEvent兼容IE低版本

e.stopPropagation会阻止冒泡 ------e.preventDefault()

  • 利用事件冒泡实现:
$("ul").on("mouseover",function(e){
    $(e.target).css("background-color","#ddd").siblings().css("background-color","white");
})
复制代码

10、DOM0级事件与DOM2级事件

事件的传播分为两个阶段:捕获阶段、冒泡阶段(先捕获在冒泡)

  • DOM零级事件绑定我们能够看到和控制的只有冒泡阶段:子元素的行为触发,父元素的相关行为也会触发,父元素的父元素的相关行为也会触发...
  • DOM二级事件绑定可以看到和控制两个阶段
  • DOM二级事件绑定:addEventListener:[type],[function],true:在捕获阶段执行/false:在冒泡阶段完成
  • 阻止事件冒泡传播:e.stopPropagation()、cancelBubble=true(ie阻止事件冒泡传播)
  • 阻止浏览器默认行为:preventDefault()、returnValue=false(ie)

事件对象e本身也存在兼容问题:在标准浏览器中是浏览器默认传递的形参值e、在IE6~8下我们使用的是全局对象window下的event属性 e=e||window.event;

  • e.type 存储的是当前的事件行为类型,例如:"click"...
  • e.target 存储的是事件源(当前事件发生在哪个元素上) 这个属性不兼容:e.srcElement 例如:e.target=e.target||e.srcElement;
  • e.clientX/e.clientY:鼠标触发点距离当前屏幕窗口左上角的X和Y轴的偏移值
  • e.pageX/e.pageY:鼠标触发点距离整个文档(第一屏)左上角的X和Y轴的偏移值 但是在IE下是不存在这个属性的
  • e.pageY=e.pageY||(e.clientY+(document.documentElement.scrollTop||document.body.scrollTop));
  • e.preventDefault ? e.preventDefault() : e.returnValue = false; ---阻止事件的默认行为
  • e.stopPropagation ? e.stopPropagation() : e.cancelable = true; ---阻止事件的冒泡传播
oDiv.onclick = function (e) {
    e = e || window.event;
}
复制代码

在IE6~8下不兼容我们的addEventListener这个方法---attachEvent("on"+eventType,eventFn) 只有在冒泡阶段发生 (detachEvent移除事件绑定)

10.1 DOM二级事件相对于DOM0级事件的好处:

  • DOM2级事件可以相对比较灵活的控制我们的传播机制
  • DOM0级事件只能给一个元素的同一个事件类型绑定一个方法,绑定的第二个方法会把我们的第一个覆盖掉;而DOM2级事件可以给一个元素的同一个事件类型绑定多个不同的方法(这些方法都存在事件池中,当我点击的时候,这些方法都会一个个的执行);
  • DOM0中的事件类型在DOM2中都可以使用,但是DOM2级事件绑定中提供了一些DOM0没有的事件类型:DOMContentLoaded(HTML结构加载完成)...

10.2 关于DOM2事件的兼容问题

标准浏览器下使用addEventListener(removeEventListener)实现我们的添加和删除;在IE6~8下使用attachEvent(detachEvent)实现绑定和删除;

  • this指向问题:addEventListener绑定的那个方法中的this是当前操作的元素;而attachEvent绑定方法中的this是window
  • 重复问题:addEventListener给一个元素的同一个事件类型如果绑定了多个相同的方法,默认只执行其中的一个;但是attachEvent不管是否重复都会执行;
  • 顺序问题:addEventListener给一个元素的同一个事件类型绑定多个不同的方法,那么这些方法会按照绑定的先后顺序放入到事假池中,当执行的时候,也同样按照绑定的先后顺序执行;但是attachEvent执行的顺序和绑定的顺序没啥关系,执行的时候,顺序是混乱的;

11、Set 和 Map 数据结构

  • ES6 提供了新的数据结构 Set 它类似于数组,但是成员的值都是唯一的,没有重复的值。
  • ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

12、浏览器缓存

浏览器缓存分为强缓存和协商缓存。当客户端请求某个资源时,获取缓存的流程如下:

  • 先根据这个资源的一些 http header判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器;
  • 当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源;
  • 强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源;
  • 区别是,强缓存不对发送请求到服务器,但协商缓存会。
  • 当协商缓存也没命中时,服务器就会将资源发送回客户端。
  • 当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
  • 当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存;

强缓存

  • Expires(该字段是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)
  • Cache-Control:max-age(该字段是 http1.1 的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)

协商缓存

  • Last-Modified(值为资源最后更新时间,随服务器response返回)
  • If-Modified-Since(通过比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存)
  • ETag(表示资源内容的唯一标识,随服务器response返回)
  • If-None-Match(服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存)

13、CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?

  • CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。

  • ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。

  • import/export 最终都是编译为 require/exports 来执行的。

  • CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。

  • export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

14、项目做过哪些性能优化?

  • 减少 HTTP 请求数
  • 减少 DNS 查询
  • 使用 CDN
  • 避免重定向
  • 图片懒加载
  • 减少 DOM 元素数量
  • 减少 DOM 操作
  • 使用外部 JavaScript 和 CSS
  • 压缩 JavaScript 、 CSS 、字体、图片等
  • 优化 CSS Sprite
  • 使用 iconfont
  • 字体裁剪
  • 多域名分发划分内容到不同域名
  • 尽量减少 iframe 使用
  • 避免图片 src 为空
  • 把样式表放在 中
  • 把脚本放在页面底部

vue问题

1、Vue router 除了 router-link 怎么实现跳转?

router.go(1)
router.push('/')
复制代码

2、Vue router 跳转和 location.href 有什么区别?

router 是 hash 改变

location.href 是页面跳转,刷新页面

3、Vue 双向绑定实现原理?

通过 Object.defineProperty 实现的

4、你能实现一下双向绑定吗?

<body>
    <div id="app">
        <input type="text" id="txt">
        <p id="show-txt"></p>
    </div>
    <script>
        var obj = {}
        Object.defineProperty(obj, 'txt', {
            get: function () {
                return obj
            },
            set: function (newValue) {
                document.getElementById('txt').value = newValue
                document.getElementById('show-txt').innerHTML = newValue
            }
        })
        document.addEventListener('keyup', function (e) {
            obj.txt = e.target.value
        })
    </script>
</body>
复制代码

摘取文章:

https://blog.ihoey.com/posts/Interview/2018-02-28-alibaba-interview.html