怎么去设计一个组件封装
-
组件封装的目的是为了重用,提高开发效率和代码质量
-
低耦合,单一职责,可复用性,可维护性
-
前端组件化设计思路
js 异步加载的方式
-
渲染引擎遇到 script 标签会停下来,等到执行完脚本,继续向下渲染
-
defer 是“渲染完再执行”,async 是“下载完就执行”,defer 如果有多个脚本,会按照在页面中出现的顺序加载,多个async 脚本不能保证加载顺序
-
加载 es6模块的时候设置 type=module,异步加载不会造成阻塞浏览器,页面渲染完再执行,可以同时加上async属性,异步执行脚本(利用顶层的this等于undefined这个语法点,可以侦测当前代码是否在 ES6 模块之中)
css 动画和 js 动画的差异
-
代码复杂度,js 动画代码相对复杂一些
-
动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css动画不能添加事件
-
动画性能看,js 动画多了一个js 解析的过程,性能不如 css 动画好
XSS 与 CSRF 两种跨站攻击
-
xss 跨站脚本攻击,主要是前端层面的,用户在输入层面插入攻击脚本,改变页面的显示,或则窃取网站 cookie,预防方法:不相信用户的所有操作,对用户输入进行一个转义,不允许 js 对 cookie 的读写
-
csrf 跨站请求伪造,以你的名义,发送恶意请求,通过 cookie 加参数等形式过滤
-
我们没法彻底杜绝攻击,只能提高攻击门槛
事件委托,目的,功能,写法
-
把一个或者一组元素的事件委托到它的父层或者更外层元素上
-
优点,减少内存消耗,动态绑定事件
-
target 是触发事件的最具体的元素,currenttarget是绑定事件的元素(在函数中一般等于this)
-
JavaScript 事件委托详解
线程,进程
-
线程是最小的执行单元,进程是最小的资源管理单元
-
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程
负载均衡
-
当系统面临大量用户访问,负载过高的时候,通常会使用增加服务器数量来进行横向扩展,使用集群和负载均衡提高整个系统的处理能力
-
服务器集群负载均衡原理?
什么是CDN缓存
-
CDN 是一种部署策略,根据不同的地区部署类似nginx 这种服务服务,会缓存静态资源。前端在项目优化的时候,习惯在讲台资源上加上一个 hash 值,每次更新的时候去改变这个 hash,hash 值变化的时候,服务会去重新取资源
-
(CDN)是一个经策略性部署的整体系统,包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件
-
CDN_百度百科
闭包的写法,闭包的作用,闭包的缺点
-
使用闭包的目的——隐藏变量,间接访问一个变量,在定义函数的词法作用域外,调用函数
-
闭包的内存泄露,是IE的一个 bug,闭包使用完成之后,收回不了闭包的引用,导致内存泄露
-
「每日一题」JS 中的闭包是什么?
-
闭包造成内存泄露的实验
跨域问题,谁限制的跨域,怎么解决
-
浏览器的同源策略导致了跨域
-
用于隔离潜在恶意文件的重要安全机制
-
[jsonp ,允许 script 加载第三方资源]https://segmentfault.com/a/11...
-
nginx 反向代理(nginx 服务内部配置 Access-Control-Allow-Origin *)
-
cors 前后端协作设置请求头部,Access-Control-Allow-Origin 等头部信息
-
iframe 嵌套通讯,postmessage
javascript 中常见的内存泄露陷阱
-
内存泄露会导致一系列问题,比如:运行缓慢,崩溃,高延迟
-
内存泄露是指你用不到(访问不到)的变量,依然占居着内存空间,不能被再次利用起来
-
意外的全局变量,这些都是不会被回收的变量(除非设置 null 或者被重新赋值),特别是那些用来临时存储大量信息的变量
-
周期函数一直在运行,处理函数并不会被回收,jq 在移除节点前都会,将事件监听移除
-
js 代码中有对 DOM 节点的引用,dom 节点被移除的时候,引用还维持
-
JavaScript 中 4 种常见的内存泄露陷阱
babel把ES6转成ES5或者ES3之类的原理是什么
-
它就是个编译器,输入语言是ES6+,编译目标语言是ES5
-
babel 官方工作原理
-
解析:将代码字符串解析成抽象语法树
-
变换:对抽象语法树进行变换操作
-
再建:根据变换后的抽象语法树再生成代码字符串
Promise 模拟终止
-
当新对象保持“pending”状态时,原Promise链将会中止执行。
-
return new Promise(()=>{}); // 返回“pending”状态的Promise对象
-
从如何停掉 Promise 链说起(promise内存泄漏问题)
promise 放在try catch里面有什么结果
-
Promise 对象的错误具有冒泡性质,会一直向后传递,直到被捕获为止,也即是说,错误总会被下一个catch语句捕获
-
当Promise链中抛出一个错误时,错误信息沿着链路向后传递,直至被捕获
网站性能优化
-
http 请求方面,减少请求数量,请求体积,对应的做法是,对项目资源进行压缩,控制项目资源的 dns 解析在2到4个域名,提取公告的样式,公共的组件,雪碧图,缓存资源,
-
压缩资源,提取公共资源压缩,提取 css ,js 公共方法
-
不要缩放图片,使用雪碧图,使用字体图表(阿里矢量图库)
-
使用 CDN,抛开无用的 cookie
-
减少重绘重排,CSS属性读写分离,最好不要用js 修改样式,dom 离线更新,渲染前指定图片的大小
-
js 代码层面的优化,减少对字符串的计算,合理使用闭包,首屏的js 资源加载放在最底部
js 自定义事件实现
-
原生提供了3个方法实现自定义事件
-
createEvent,设置事件类型,是 html 事件还是 鼠标事件
-
initEvent 初始化事件,事件名称,是否允许冒泡,是否阻止自定义事件
-
dispatchEvent 触发事件
angular 双向数据绑定与vue数据的双向数据绑定
-
二者都是 MVVM 模式开发的典型代表
-
angular 是通过脏检测实现,angular 会将 UI 事件,请求事件,settimeout 这类延迟,的对象放入到事件监测的脏队列,当数据变化的时候,触发 $diget 方法进行数据的更新,视图的渲染
-
vue 通过数据属性的数据劫持和发布订阅的模式实现,大致可以理解成由3个模块组成,observer 完成对数据的劫持,compile 完成对模板片段的渲染,watcher 作为桥梁连接二者,订阅数据变化及更新视图
get与post 通讯的区别
-
Get 请求能缓存,Post 不能
-
Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,且会被浏览器保存历史纪录,Post 不会,但是在抓包的情况下都是一样的。
-
Post 可以通过 request body来传输比 Get 更多的数据,Get 没有这个技术
-
URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
-
Post 支持更多的编码类型且不对数据类型限制
有没有去研究webpack的一些原理和机制,怎么实现的
-
解析webpack配置参数,合并从shell传入和webpack.config.js文件里配置的参数,生产最后的配置结果。
-
注册所有配置的插件,好让插件监听webpack构建生命周期的事件节点,以做出对应的反应。
-
从配置的entry入口文件开始解析文件构建AST语法树,找出每个文件所依赖的文件,递归下去。
-
在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件进行转换。
-
递归完后得到每个文件的最终结果,根据entry配置生成代码块chunk。
-
输出所有chunk到文件系统。
ES6模块与CommonJS模块的差异
-
CommonJs 模块输出的是一个值的拷贝,ES6模块输出的是一个值的引用
-
CommonJS 模块是运行时加载,ES6模块是编译时输出接口
-
ES6输入的模块变量,只是一个符号链接,所以这个变量是只读的,对它进行重新赋值就会报错
模块加载AMD,CMD,CommonJS Modules/2.0 规范
-
这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的
-
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行
-
CMD 推崇依赖就近,AMD 推崇依赖前置
Node 事件循环,js 事件循环差异
-
Node.js 的事件循环分为6个阶段
-
浏览器和Node 环境下,microtask 任务队列的执行时机不同
-
Node.js中,microtask 在事件循环的各个阶段之间执行
-
浏览器端,microtask 在事件循环的 macrotask 执行完之后执行
-
-
递归的调用process.nextTick()会导致I/O starving,官方推荐使用setImmediate()
浅拷贝和深拷贝的问题
-
深拷贝和浅拷贝是只针对Object和Array这样的复杂类型的
-
也就是说a和b指向了同一块内存,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
-
浅拷贝, ”Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
-
深拷贝,JSON.parse()和JSON.stringify()给了我们一个基本的解决办法。但是函数不能被正确处理
请描述 cookies、sessionStorage 和 localStorage 的区别。
软件编程希望通过一些手段来持久化的存储一些有用的数据。对于网络化编程,一般将这项任务交给了服务器端的数据库或者浏览器端的cookie。随着HTML5的出现,web开发又有了两种选择:Web Storage和Web SQL Database.
WebStorage有两种形式:LocalStorage(本地存储)和sessionStorage(会话存储)。这两种方式都允许开发者使用js设置的键值对进行操作,在在重新加载不同的页面的时候读出它们。这一点与cookie类似。
1:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
2:存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
3:数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
4:作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
5:Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
6:Web Storage 的 api 接口使用更方便。
请解释 <script>、<script async> 和 <script defer> 的区别。
向html页面中插入javascript代码的主要方法就是通过script标签。其中包括两种形式,第一种直接在script标签之间插入js代码,第二种即是通过src属性引入外部js文件。由于解释器在解析执行js代码期间会阻塞页面其余部分的渲染,对于存在大量js代码的页面来说会导致浏览器出现长时间的空白和延迟,为了避免这个问题,建议把全部的js引用放在</body>标签之前。
script标签存在两个属性,defer和async,因此script标签的使用分为三种情况:
1.<script src="example.js"></script>
没有defer或async属性,浏览器会立即加载并执行相应的脚本。也就是说在渲染script标签之后的文档之前,不等待后续加载的文档元素,读到就开始加载和执行,此举会阻塞后续文档的加载;
2.<script async src="example.js"></script>
有了async属性,表示后续文档的加载和渲染与js脚本的加载和执行是并行进行的,即异步执行;
3.<script defer src="example.js"></script>
有了defer属性,加载后续文档的过程和js脚本的加载(此时仅加载不执行)是并行进行的(异步),js脚本的执行需要等到文档所有元素解析完成之后,DOMContentLoaded事件触发执行之前。
为什么通常推荐将 CSS <link> 放置在 <head></head> 之间,而将 JS <script> 放置在 </body> 之前?你知道有哪些例外吗?
如果把javascript放在head里的话,则先被解析,但这时候body还没有解析。(常规html结构都是head在前,body在后)如果head的js代码是需要传入一个参数(在body中调用该方法时,才会传入参数),并需调用该参数进行一系列的操作,那么这时候肯定就会报错,因为函数该参数未定义(undefined)。
而为什么我们经常看到有很多的人把js脚本放到head里面都不担心出问题?因为通常把javascript放在head里的话,一般都会绑定一个监听,当全部的html文档解析完之后,再执行代码
html 渐进式渲染
你需要尽早将 HTML 字节给到浏览器。
比如:一个请求进来了,(理想状态下)你的数据被缓存起来,因此服务器能够快速获取。然后,浏览器开始解析数据,并在屏幕上呈现出来。
对于此次 WebPageTest,在 1.5 秒就得到了第一屏,但是你能看到,它没有包含所有内容。它包含的内容足以让你开始浏览页面、或查看假日交易。
然后,到 3.5 秒,另一部分载入了更多交易。到 6.5 秒,一些东西仍然在载入!事实上,整个页面载入的完成一直持续到 18 秒。你能等那么长时间吗?我表示怀疑!
如果 Amazon 专注于最慢的页面载入,那么一定有人被激怒。他们却专注于在最早的 packet 里发送最重要的字节。再进一步,他们可能在第一个 packet 里塞满最重要的字节。我敢打赌,他们还专注于尽快地为你发送那些字节。
CSS 中类 (classes) 和 ID 的区别。
在样式表定义一个样式的时候,可以定义id也可以定义class。
在CSS文件里书写时,ID加前缀“#”;CLASS用“.”
id一个页面只可以使用一次;class可以多次引用。
ID是一个标签,用于区分不同的结构和内容,就象名字,如果一个屋子有2个人同名,就会出现混淆;class是一个样式,可以套在任何结构和内容上,就象一件衣服;
目前的浏览器还都允许用多个相同ID,一般情况下也能正常显示,不过当你需要用JavaScript通过id来控制div时就会出现错误。
从概念上说就是不一样的:id是先找到结构/内容,再给它定义样式;class是先定义好一种样式,再套给多个结构/内容。
请问 “resetting” 和 “normalizing” CSS 之间的区别?你会如何选择,为什么?
reset.css能够重置浏览器的默认属性。不同的浏览器具有不同的样式,重置能够使其统一。比如说ie浏览器和FF浏览器下button显示不同,通过reset能够统一样式,显示相同的想过。但是很多reset是没必要的,多写了会增加浏览器在渲染页面的负担。 比如说,我们不应该对行内元素设置无效的属性,对span设置width和height,margin都不会生效的。
对于absolute和fixed定位的固定尺寸(设置了width和height属性),如果设置了top和left属性,那么bottom和right,margin和float就没有作用。
后面设置的属性将会覆盖前面重复设置的属性。期待能够指出它的负面影响,或者提到它的一个更好的替换者“normalize”
normalize.css是一个可以定制的css文件,它让不同的浏览器在渲染元素时形式更统一。
请解释浮动 (Floats) 及其工作原理。
float属性定义了元素是否浮动及在哪个方向浮动,在CSS中任何元素都可以浮动,且浮动元素会生成一个块级框,而不论它本身是何种元素。并且盒子的宽度不在伸展,而是根据盒子里面的内容的宽度来确定。浮动属性会使得浮动的元素脱离文档流,所以文档的普通流中的块框会表现的像浮动框不存在一样。
开放性问题
开放性问题主要是考察候选人业务积累,是否有自己的思考,思考问题的方式,没有标准答案。不过有些问题挺刁的,哈哈哈哈,比如:" 你见过的最好的代码是什么? "总之提前准备下没错。
-
先自我介绍一下,说一下项目的技术栈,以及项目中遇到的一些问题
-
从整体中,看你对项目的认识,框架的认识和自己思考
-
项目中有没有遇到什么难点,怎么解决
-
如果你在创业公司你怎么从0开始做(选择什么框架,选择什么构建工具)
-
说一下你项目中用到的技术栈,以及觉得得意和出色的点,以及让你头疼的点,怎么解决的
-
一个业务场景,面对产品不断迭代,以及需求的变动该怎么应对,具体技术方案实现
-
你的学习来源是什么
-
你觉得哪个框架比较好,好在哪里
-
你觉得最难得技术难点是什么
-
你见过的最好的代码是什么