前端面试题记录 -- 遇到过的面试题笔记

一、HTML语义化
根据内容的结构化,代码的语义化选择合适的标签,便于开发者阅读和编写优雅的代码的同时便于浏览器的爬虫和机器很好的解析,在没没有css的情况下页面也能呈现出很好的内容结构和代码结构,有利于SEO和搜索引擎建立良好沟通,有助于搜索引擎的爬虫和机器抓取更多有效的信息,爬虫依赖于上下文各个关键字的权重

二、opp、继承、原型链、闭包、es6新特性
opp面向对象是一种编程思想,用一句话说就是封装、继承、多态,javascript是弱类型语言天然具备多态的特性,使用函数进行封装,通过原型实现继承
原型的作用:解决数据共享,节省内存空间
原型:在构造函数创建的时候,系统会默认的会为这个构造函数创建并关联一个对象,这个对象就是原型对象,这个原型对象默认是一个空的对象,该对象中的所有成员可以被所有通过构造函数实例化出来的对象所访问
原型链:原型对象也是普通对象,对象都自带一个隐式的proto属性,原型也有可能有自己的原型,如果一个原型的对象的原型不为null,我们就成为原型链,每一个构造函数都有原型对象,每一个原型对象都有构造函数,这样就形成了一个链式结构,称之为原型链。
闭包:函数A里有函数B,函数B可以访问函数A的变量,用一句话说就是拿到你不该拿的东西,只执行函数也是闭包,也叫沙箱,就是让内部变量不会污染全局
闭包的特性: 可以读取函数内部变量,将函数内变量始终保存在内存中不会污染全局,保护函数内部变量不被更改。
闭包的优点:缓存数据,实现封装防止变量跑到外层作用域中,发生命名冲突,匿名只执行函数可以减少内存消耗。
es6: let和const声明变量(只在当前代码块中有效,相当于创建了块级作用域)和常量(可以更改对象里属性,变量的解构赋值),箭头函数,数组的拓展,模块化

三、AJAX、jsonp、xml、json、CORS、跨域
ajax是一种创建交互式网页应用的网页开发技术,主要用来实现客户端与服务器的异步通信效果,实现页面局部刷新,发送请求主要通过XMLHttpRequest,ActiveObject对象实现异步通信效果
优点: 实现页面局部刷新,带来更好的用户体验,按需获取数据,节省带宽资源
缺点:不支持浏览器back按钮 、安全问题 ajax暴露了与服务器交互的细节、对搜索引擎的支持比较弱、破坏了程序的异常机制

ajax请求时get和post的区别?
get一般用来进行查询操作,URL地址有长度限制,请求的参数都暴露才URL地址中,如果参数传递中文,需要自己进行编码操作,安全性较低
post一般用来提交数据,没有数据长度的限制,提交数据内容存在与http请求头总,数据不会暴露在URL地址中
jsonp: 是一种跨域解决方案,动态创建script标签,通过标签的src属性获取js文件中的js脚本,js载入成功后执行我们在URL参数中的指定的函数,并且会把我们需要的json数据作为参数传入

为什么会出现跨域?
由于同源策略的限制,XMLHttpRequest只
允许请求当前源的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务器输出json数据并执行回调函数,从而解决了跨域的数据请求
优点是兼容性好,简单易用,支持浏览器与服务器双向通信,缺点是只支持get请求,不能很好的发现错误并惊醒处理,与ajax对于,,由于不是通过XMLHttpRequest进行传输,所以不能注册success、error等事件监听函数

xml和json的区别?
1、数据体积方面 json数据的体积小,传递数据更快
2、数据交互方面 json和js的交互更加方便,更容易解析
3、数据描述方面 json的数据描述性比xml差
4、传输速度方面 json的速度远远快与xml
CORS
cors跨域共享资源,主要是通过对access-control-allow-origin来进行的,如果浏览器检查到相应设置,就允许访问,jsonp的现代版
CORS和JSONP对比?
1、cors除了get方法外,也支持其他的http请求,如post
2、cors可以使用XMLHttpRequest进行传输,所以它的错误处理方式比jsonp好
3、jsonp可以在不支持cors的老旧浏览器上运作

其他一些跨域方式
1、Window.domain 来跨子域,要求,必须是同一域名下的,端口协议相同
2、window.name,window对象有个name属性,该属性有个特征,在一个窗口的生命周期内,每个页面共享一个Window.name,每个页面都对window.name有读写权限,window.name是持久存在一个窗口载入过的所有页面中的 ,并不会因为页面的载入而进行重置
3、window.postMessage H5 的新特性,可以用来像所有的window对象发送消息,但必须保证页面的所有的脚本执行完毕才发送messageEvent,如果在函数执行的过程中调用它,那么后面的函数超时无法执行

四、前端模块化
AMD 依赖前置 提前执行 是requirejs在推广过程中对模块定义的规范化产出
requirejs 实现文件的异步加载,避免网页失去响应,管理模块间的依赖,便于代码的编写和维护

CMD 就近依赖 延迟执行 是seaJS在推广过程中对模块定义的规范化产出
AMD推荐的风格通过返回一个对象作为模块对象,commonjs的风格通过对module.exports或exports的属性赋值来达到暴露模块的目的

五、版本控制器SVN\Git 项目构建工具 gulp、grunt、webpack
1、版本控制器 SVN、git区别

    1.   最核心的区别是git是分布式的,SVN不是    
    2.  git存储数据按数据方式存储,SVN按文件存储     
    3.  git和SVN分支不同      
    4.  git没有一个全局的版本 ,SVN有 5) git内容完整性优于SVN
git特点,版本控制可以不依赖与网络做任何事情,对分支合并更好的支持
git文件的四种状态 未追踪 untracked 已提交 committed  已修改 modified  已暂存 staged

2、grunt 是一套前端自动化工具,基于nodejs的命令行工具,一般用于:压缩文件,合并文件,简单语法检查

3、gulp 基于nodejs开发的一个构建工具,借助gulp插件可以构建任务,通过require可以引入一个nodejs的包其作用类似于浏览器中的script标签引入资源,被引入的包存放在node_modules目录下,引入gulp包后返回一个对象,习惯赋值给变量gulp,通过该对象提供的方法完成任务的配置

常用插件:  1) gulp-concat  文件合并   
          2) 文件拷贝 gulp-copy   
          3) gulp-uglify js压缩    
          4)gulp-replace 文本替换   
          5) gulp-imgmin 图片压缩  
          6)gulp-cssmin  css压缩    
          7) gulp-rev 添加版本号   
          8)gulp-rename 重命名         

gulp API:

     1)gulp.task()定义各种不同的任务   
     2)gulp.src()  需要构建的资源的路径  
     3) gulp-pipe()  管道 将需要构建的资源传送给插件   
     4) gulp-dest  构建完成后资源的存放路径   
     5) gulp.watch 

4、webpack 前端资源模块化管理和打包工具,它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行分隔,等到实际需要的时候再异步架加载。通过loader的转换,任何形式的资源都可以视作模块,比如commonjs模,AMD模块,ES6模块,图片、css、json、coffeescript、less等…

5、bower web开发中的一个前端文件包管理器,JavaScript、CSS、HTML、图像或字体。依托于 Node.js,类似于node模块的npm包管理器,它允许开发者为服务器编写可共享的模块,它是基于git运行的,依赖于git、node和npm
webpack和gulp区别
gulp强调的是前端开发的工作流程,通过配置一系列的task,定义tack处理的事务(文件压缩、雪碧图、启动server、版本控制等),然后定义执行顺序,让gulp执行这些task,从而构建项目的整个前端开发流程, TASK Runter gulp旨在规范前端开发流程
webpack是一个前端模块化方案,更侧重于打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源 webpack is a module bundle webpack强调模块化开发
Gulp侧重整个过程的控制,Webpack在模块打包方面有特别出众。所以,Gulp + Webpack 组合使用可能更方便。

六、promise的三种状态

1、pending 待发,没有在内部记录成功resolve或失败reject的时候
2、resolved 已解决
3、rejected 已拒绝
未来是在then里面能后通过不同的记录的状态,调不同的回调函数, 
如果成功,then,如果失败,catch,也可以内部传递参数和接受参数, 
promise中的状态一经改变无法回退

七、渐进增强与优雅降级
渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,再针对高版本浏览器进行效果、交互等改进和追加达到更好的用户体验
优雅降级:一开始就构建完整的功能,然后再针对低版本的浏览器进行兼容

八、常见web安全及防护原理
sql注入原理就是通过吧SQL命令插入到web表单递交或者输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
防范措施:
1、永远不要相信用户的输入,要多用户的输入进行校验,可以通过正则表达式或者限制长度
2、永远不要使用动态拼装SQL,可以使用参数化的或者直接使用存储过程直接进行数据查询存取
3、永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4、不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。

九、XSS原理及防范
xss指的是攻击者往web页面插入恶意的HTML标签或者javascript代码,比如攻击者在论坛上放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息,或者攻击者在论坛中加一个恶意的表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是原本以为信任的站点

xss防范: 首先代码里对用户输入的地方和变量都需要仔细检查长度和对特殊字符做过滤,其次任何内容写到页面之前都必须加encode,避免一不小心把etag弄出来,这样至少可以堵住超过一半的XSS攻击。首先,避免直接在cookie中泄露用户隐私,例如email、密码等等。其次,通过使cookie和系统ip绑定来降低cookie泄露后的危险。这样攻击者得到的cookie没有实际价值,不可能拿来重放。
如果网站不需要再浏览器端对cookie进行操作,可以在Set-Cookie末尾加上HttpOnly来防javascript代码直接获取cookie。尽量采用POST而非GET提交表单

十、XSS与CSRF有什么区别吗?
XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。
要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1、登录受信任网站A,并在本地生成Cookie。在不登出A的情况下,访问危险网站B。
CSRF的防御:服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
2、通过验证码的方法

十一、Web Worker 和webSocket
worker主线程:
1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。
2.通过worker.postMessage( data ) 方法来向worker发送数据。
3.绑定worker.onmessage方法来接收worker发送过来的数据。
4.可以使用 worker.terminate() 来终止一个worker的执行。
WebSocket是Web应用程序的传输协议,它提供了双向的,按序到达的数据流。他是一个HTML5协议,WebSocket的连接是持久的,他通过在客户端和服务器之间保持双工连接,服务器的更新可以被及时推送给客户端,而不需要客户端以一定时间间隔去轮询。

十二、http和https
http协议通过承载与tcp协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS。
默认HTTP的端口号为80,HTTPS的端口号为443。
为什么HTTPS安全
因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有。https之所以比http安全,是因为他利用ssl/tls协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等。保障了传输过程的安全性

十三、性能优化
1、避免使用css表达式,避免使用高级选择器,通配符选择器
2、缓存ajax、使用cdn缓存、使用外部js和css文件以便缓存、添加expiress头
3、合并样式和脚本,使用css精灵图,初始化除首屏之外的图片资源按需加载
4、压缩文件、开启gzip
5、少用全局变量,使用hash-table来优化查找,避免全局查询
6、用innerHTML代替DOM操作,减少DOM操作次数,优化javascript代码
7、用settimeout来避免网页失去响应
8、缓存DOM节点查找的结果
9、避免使用with (with会创建自己的作用域,会增加作用域链的长度)
10、避免iframe等空的src,空的src会重新加载当前页面,影响加载速度
11、避免在HTML中使用style属性
移动端优化
1、尽量使用css3动画,开启硬件加速。
2、适当使用touch事件代替clock时间
3、避免使用css3渐变阴影效果
4、可以使用transform:translateZ(0)来开启硬件加速
5、不滥用float、float在渲染时计算量比较大,尽量减少使用
6、不滥用web字体,web字体需要下载,解析,重绘当前页面
7、合理使用requestAnimationFrame动画代替settimeout
8、CSS中的属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发GPU渲染,请合理使用。过渡使用会引发手机过耗电增加

十四、 Web APP
Web App 指采用Html5语言写出的App,不需要下载安装。类似于现在所说的轻应用。生存在浏览器中的应用,基本上可以说是触屏版的网页应用。
优点
(1)开发成本低,
(2)更新快,
(3)更新无需通知用户,不需要手动升级
(4)能够跨多个平台和终端。
缺点:
(1)临时性的入口
(2)无法获取系统级别的通知,提醒,动效等等
(3)用户留存率低
(4)设计受限制诸多
(5)体验较差

十五、 Hybrid App
Hybrid APP指的是半原生半Web的混合类App。需要下载安装,看上去类似Native App,但只有很少的UI Web View,访问的内容是 Web 。
例如Store里的新闻类APP,视频类APP普遍采取的是Native的框架,Web的内容。
Hybrid App 极力去打造类似于Native App 的体验,但仍受限于技术,网速,等等很多因素。尚不完美。

十六、 Native App
Native APP 指的是原生程序,一般依托于操作系统,有很强的交互,是一个完整的App,可拓展性强。需要用户下载安装使用。
优点:
(1)打造完美的用户体验
(2)性能稳定
(3)操作速度快,上手流畅
(4)访问本地资源(通讯录,相册)
(5)设计出色的动效,转场,
(6)拥有系统级别的贴心通知或提醒
(7)用户留存率高
缺点:
(1)分发成本高(不同平台有不同的开发语言和界面适配)
(2)维护成本高(例如一款App已更新至V5版本,但仍有用户在使用V2, V3, V4版本,需要更多的开发人员维护之前的版本)
(3)更新缓慢,根据不同平台,提交–审核–上线 等等不同的流程,需要经过的流程较复杂

笔试题部分

数组方法
 pop 删除数组最后一位元素   push 向数组末尾添加一个或多个元素
shift 删除数组第一位元素     unshift 向数组的开头添加一个或多个元素
reverse 把数组元素顺序逆转 (倒序) sort  数组顺序排序 
 splice 给数组添加或者删除元素  splice(开始下标, 删除个数,插入元素(可以多个))
 join 合并数组所有元素拼接成字符串  concat 合并数组或合并数组的值。
1、实现div移动
animation: mydv 5s linear infinite;
    @keyframes mydv {
            0% {
                transform: translateX(0px);
            }
            100% {
                transform: translateX(500px);
            }
        }
2、转URL对象
 function getParams(url){
            if(url === undefined || typeof(url) != 'string'){
                return null;
            }
            var items = url.split('?')[1].split('&');
            var json = {};
            for(var i = 0; i < items.length; i++){
                var item = items[i].split('=');
                json[item[0]] = item[1];
            }
            return json;
        }
        var url = 'http://www.taobao.com/item.html?a=1&b=2&c=3&d=xxx&e';
    console.log(getParams(url));
3、验证手机号是否合法
function mobile() {
            var reg = /^1[1|3|4|5|7|8][0-9]{9}$/;
            if(!(reg.test(txt.value))){
                alert("对不起,您输入的手机号不合法,请重新输入");
            }else{
                alert("验证成功");
            }
        }
4、 去除首尾空格
function trimStr(str){
  return str.replace(/(^\s*)|(\s*$)/g,"");
}

5、冒泡排序(比较两个相邻的元素,如果第一个比第二个大就交换位置)

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

6、快速排序(找一个数作为基准,比基准大的放右边,比基准小的放左边,相等放随意两遍,然后递归调用合并到一起)

function quickSort(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))
}

7、双向数据绑定

var obj = {};
Object.defineProperty(obj, 'userName', {
    get: function () {

    },
    set: function (val) {
        input.value = val;
        span.innerText = val;
    }
})
input.addEventListener('keyup', function (ev) {
    var target = ev.target || ev.srcElement
    obj.userName = target.value
})


   8、数组去重(建一个新数组,如果新数组中没有这个数则放到数组中)
function unique(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) == -1) {
            newArr.push(arr[i])
        }
    }
    return newArr;
}

8.1、数组去重(把数组排序,建一个新数组,拿出数组中的第一个数,如果后面的数不重复则放到数组中)

function unique1(arr) {
    if (arr.length <= 1) {
        return arr;
    }
    var arr2 = arr.sort();
    var res = [arr2[0]]
    for (var i = 0; i < arr2.length; i++) {
        if (arr2[i] !== res[res.length - 1]) {
            res.push(arr[i])
        }
    }
    return res;
}

9、克隆五种数据类型(如果是数组和对象递归调用自己,普通变量直接赋值)
instanceof用于判断一个变量是否某个对象的实例

function clone(obj) {
    var buf;
    if (obj instanceof Array) {
        buf = []
        var i = obj.length
        while (i--) {
            buf[i] = clone(obj[i])
        }
        return buf;
    } else if (obj instanceof Object) {
        buf = {};
        for (var k in obj) {
            buf[k] = clone(Obj[k]);
        }
        return buf;
    } else {
        return obj
    }
}

10、获取URL查询字符串的参数
function showWindowHref(str) {
    var spliArr = str.split("?");
    if (spliArr[0] === str) {
        return;
    }
    var paramsStr = spliArr[1];//channelid=12333&name=xiaoming&age=23
    var mParamsArr = paramsStr.split("&");// [channelid=12333,name=xiaoming,age=23]
    var obj = {};
    for (var i = 0; i < mParamsArr.length; i++) {
        obj[mParamsArr[i].split("=")[0]] = mParamsArr[i].split("=")[1];
    }
    return obj;
}

11、求一个字符串出现次数最多的字符和出现的次数
var obj = {};
var len = s.length;
for (var i = 0; i < len; i++) {
    if (!obj[s.charAt(i)]) {
        obj[s.charAt(i)] = 1;
    } else {
        obj[s.charAt(i)]++;
    }
}
var targetStr = "";
var mostTime = 0;
for (var k in obj) {
    if (mostTime < obj[k]) {
        mostTime = obj[k];
        targetStr = k;
    }
}
alert('出现次数最多的是:' + targetStr + '出现' + mostTime + '次');

12、将get - element - by - id转换为getElementById

function transStr(str) {
    var strArr = str.split("-");
    var tempStr = "";
    for (var i = 0; i < strArr.length; i++) {
        strArr[i] = strArr[i].charAt(0).toUpperCase() + strArr[i].substr(1, strArr[i].length - 1).toLowerCase();
    }
    tempStr = strArr.join("");
    return tempStr;
}

猜你喜欢

转载自blog.csdn.net/weixin_38457248/article/details/81805438