⼯商银⾏的⾸⻚不⽀持HTTPS
⽽⼯商银⾏的⽹银⻚⾯是⽀持HTTPS的
可能有⼈会问,登录⻚⾯⽀持HTTPS不就⾏了,⾸⻚⼜没有涉及账户信息. 其实这是⾮常不安全的⾏为,⿊客会利⽤这⼀点进⾏攻击,⼀般是以下流程:
- ⽤户在⾸⻚点击「登录」,⻚⾯跳转到有https的⽹银⻚⾯,但此时由于⾸⻚是http请求,所以是明⽂的,这就会被⿊客劫持
- ⿊客劫持⽤户的跳转请求,将https⽹银⻚⾯地址转换为http的地址再发送给银⾏
⽤户 <== HTTP > ⿊客 < HTTPS ==> 银⾏ - 此时如果⽤户输⼊账户信息,那么会被中间的⿊客获取,此时的账号密码就被泄露了
好在是⼯商银⾏的⽹银⻚⾯应该是开启了hsts和pre load,只⽀持https,因此上述攻击暂时是⽆效的.
中间⼈攻击
中间⼈ (Man-in-the-middle attack, MITM) 是指攻击者与通讯的两端分别创建独⽴的联系, 并交换其所收到的数据, 使通讯的两端认为他们正在通过⼀个私密的连接与对⽅直接对话, 但事实上整个会话都被攻击者完全控制. 在中间⼈攻击中, 攻击者可以拦截通讯双⽅的通话并插⼊新的内容.
⼀般的过程如下:
客户端发送请求到服务端,请求被中间⼈截获服务器向客户端发送公钥
中间⼈截获公钥,保留在⾃⼰⼿上。然后⾃⼰⽣成⼀个【伪造的】公钥,发给客户端客户端收到伪造的公钥后,⽣成加密hash值发给服务器
中间⼈获得加密hash值,⽤⾃⼰的私钥解密获得真秘钥,同时⽣成假的加密hash值,发给服务器服务器⽤私钥解密获得假密钥,然后加密数据传输给客户端
HTTPS中间⼈攻击实践
强烈建议阅读下⾯两篇前端安全⽂章:
前端安全系列(⼀):如何防⽌XSS攻击?
前端安全系列(⼆):如何防⽌CSRF攻击?
webpack⾯试题
webpack是事实上的前端打包标准,相关的⾯试题也是⾯试的热点.
webpack与grunt、gulp的不同?
Grunt、Gulp是基于任务运⾏的⼯具:
它们会⾃动执⾏指定的任务,就像流⽔线,把资源放上去然后通过不同插件进⾏加⼯,它们包含活跃的社区,丰富的插件,能⽅便的打造各种⼯作流。
Webpack是基于模块化打包的⼯具:
⾃动化处理模块,webpack把⼀切当成模块,当 webpack 处理应⽤程序时,它会递归地构建⼀个依赖关系图
(dependency graph),其中包含应⽤程序需要的每个模块,然后将所有这些模块打包成⼀个或多个 bundle。
因此这是完全不同的两类⼯具,⽽现在主流的⽅式是⽤npm script代替Grunt、Gulp,npm script同样可以打造任务流.
webpack、rollup、parcel优劣?
webpack适⽤于⼤型复杂的前端站点构建: webpack有强⼤的loader和插件⽣态,打包后的⽂件实际上就是⼀个⽴即执⾏函数,这个⽴即执⾏函数接收⼀个参数,这个参数是模块对象,键为各个模块的路径,值为模块内容。⽴即执
⾏函数内部则处理模块之间的引⽤,执⾏模块等,这种情况更适合⽂件依赖复杂的应⽤开发.
rollup适⽤于基础库的打包,如vue、d3等: Rollup 就是将各个模块打包进⼀个⽂件中,并且通过 Tree-shaking 来删除⽆⽤的代码,可以最⼤程度上降低代码体积,但是rollup没有webpack如此多的的如代码分割、按需加载等⾼级功 能,其更聚焦于库的打包,因此更适合库的开发.
parcel适⽤于简单的实验性项⽬: 他可以满⾜低⻔槛的快速看到效果,但是⽣态差、报错信息不够全⾯都是他的硬伤,除了⼀些玩具项⽬或者实验项⽬不建议使⽤
有哪些常⻅的Loader?
file-loader:把⽂件输出到⼀个⽂件夹中,在代码中通过相对 URL 去引⽤输出的⽂件
url-loader:和 file-loader 类似,但是能在⽂件很⼩的情况下以 base64 的⽅式把⽂件内容注⼊到代码中去
source-map-loader:加载额外的 Source Map ⽂件,以⽅便断点调试
image-loader:加载并且压缩图⽚⽂件babel-loader:把 ES6 转换成 ES5
css-loader:加载 CSS,⽀持模块化、压缩、⽂件导⼊等特性
style-loader:把 CSS 代码注⼊到 JavaScript 中,通过 DOM 操作去加载 CSS。eslint-loader:通过 ESLint 检查 JavaScript 代码
有哪些常⻅的Plugin?
define-plugin:定义环境变量
html-webpack-plugin:简化html⽂件创建
uglifyjs-webpack-plugin:通过 UglifyES 压缩 ES6 代码webpack-parallel-uglify-plugin: 多核压缩,提⾼压缩速度webpack-bundle-analyzer: 可视化webpack输出⽂件的体积mini-css-extract-plugin: CSS提取到单独的⽂件中,⽀持按需加载
分别介绍bundle,chunk,module是什么
bundle:是由webpack打包出来的⽂件
chunk:代码块,⼀个chunk由多个模块组合⽽成,⽤于代码的合并和分割
module:是开发中的单个模块,在webpack的世界,⼀切皆模块,⼀个模块对应⼀个⽂件,webpack会从配置的entry中递归开始找出所有依赖的模块
Loader和Plugin的不同?
不同的作⽤:
Loader直译为"加载器"。Webpack将⼀切⽂件视为模块,但是webpack原⽣是只能解析js⽂件,如果想将其他⽂件也打包的话,就会⽤到 loader 。 所以Loader的作⽤是让webpack拥有了加载和解析⾮JavaScript⽂件的能⼒。Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运⾏的⽣命周期中会⼴播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
不同的⽤法:
Loader在 module.rules 中配置,也就是说他作为模块的解析规则⽽存在。 类型为数组,每⼀项都是⼀
个 Object ,⾥⾯描述了对于什么类型的⽂件( test ),使⽤什么加载( loader )和使⽤的参数( options )
Plugin在 plugins 中单独配置。 类型为数组,每⼀项是⼀个 plugin 的实例,参数都通过构造函数传⼊。
webpack的构建流程是什么?
Webpack 的运⾏流程是⼀个串⾏的过程,从启动到结束会依次执⾏以下流程:
- 初始化参数:从配置⽂件和 Shell 语句中读取与合并参数,得出最终的参数;
- 开始编译:⽤上⼀步得到的参数初始化 Compiler 对象,加载所有配置的插件,执⾏对象的 run ⽅法开始执⾏编译;
- 确定⼊⼝:根据配置中的 entry 找出所有的⼊⼝⽂件;
- 编译模块:从⼊⼝⽂件出发,调⽤所有配置的 Loader 对模块进⾏翻译,再找出该模块依赖的模块,再递归本步骤直到所有⼊⼝依赖的⽂件都经过了本步骤的处理;
- 完成模块编译:在经过第4步使⽤ Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
- 输出资源:根据⼊⼝和模块之间的依赖关系,组装成⼀个个包含多个模块的 Chunk,再把每个 Chunk 转换成⼀个单独的⽂件加⼊到输出列表,这步是可以修改输出内容的最后机会;
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和⽂件名,把⽂件内容写⼊到⽂件系统。
在以上过程中,Webpack 会在特定的时间点⼴播出特定的事件,插件在监听到感兴趣的事件后会执⾏特定的逻辑,并且插件可以调⽤ Webpack 提供的 API 改变 Webpack 的运⾏结果。
来源于深⼊浅出webpack第五章拓展阅读细说 webpack 之流程篇
是否写过Loader和Plugin?描述⼀下编写loader或plugin的思路?
Loader像⼀个"翻译官"把读到的源⽂件内容转义成新的⽂件内容,并且每个Loader通过链式操作,将源⽂件⼀步步翻译成想要的样⼦。
编写Loader时要遵循单⼀原则,每个Loader只做⼀种"转义"⼯作。 每个Loader的拿到的是源⽂件内容( source ),可以通过返回值的⽅式将处理后的内容输出,也可以调⽤ this.callback() ⽅法,将内容返回给webpack。 还可以通过
this.async() ⽣成⼀个 callback 函数,再⽤这个callback将处理后的内容输出出去。 此外 webpack 还为开发者准备了开发loader的⼯具函数集—— loader-utils 。
相对于Loader⽽⾔,Plugin的编写就灵活了许多。 webpack在运⾏的⽣命周期中会⼴播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
webpack的热更新是如何做到的?说明其原理?
webpack的热更新⼜称热替换(Hot Module Replacement),缩写为HMR。 这个机制可以做到不⽤刷新浏览器⽽将新变更的模块替换掉旧的模块。
原理:
⾸先要知道server端和client端都做了处理⼯作
- 第⼀步,在 webpack 的 watch 模式下,⽂件系统中某⼀个⽂件发⽣修改,webpack 监听到⽂件变化,根据配置⽂件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。
- 第⼆步是 webpack-dev-server 和 webpack 之间的接⼝交互,⽽在这⼀步,主要是 dev-server 的中间件 webpack- dev-middleware 和 webpack 之间的交互,webpack-dev-middleware 调⽤ webpack 暴露的 API对代码变化进⾏监控,并且告诉 webpack,将代码打包到内存中。
- 第三步是 webpack-dev-server 对⽂件变化的⼀个监控,这⼀步不同于第⼀步,并不是监控代码变化重新打包。当我们在配置⽂件中配置了devServer.watchContentBase 为 true 的时候,Server 会监听这些配置⽂件夹中静态⽂件的变化,变化后会通知浏览器端对应⽤进⾏ live reload。注意,这⼉是浏览器刷新,和 HMR 是两个概念。
- 第四步也是 webpack-dev-server 代码的⼯作,该步骤主要是通过 sockjs(webpack-dev-server 的依赖)在浏览器端和服务端之间建⽴⼀个 websocket ⻓连接,将 webpack 编译打包的各个阶段的状态信息告知浏览器端,同时也包括第三步中 Server 监听静态⽂件变化的信息。浏览器端根据这些 socket 消息进⾏不同的操作。当然服务端传递的最主要信息还是新模块的 hash 值,后⾯的步骤根据这⼀ hash 值来进⾏模块热替换。
- webpack-dev-server/client 端并不能够请求更新的代码,也不会执⾏热更模块操作,⽽把这些⼯作⼜交回给了
webpack,webpack/hot/dev-server 的⼯作就是根据 webpack-dev-server/client 传给它的信息以及 dev-server 的
配置决定是刷新浏览器呢还是进⾏模块热更新。当然如果仅仅是刷新浏览器,也就没有后⾯那些步骤了。
6. HotModuleReplacement.runtime 是客户端 HMR 的中枢,它接收到上⼀步传递给他的新模块的 hash 值,它通过JsonpMainTemplate.runtime 向 server 端发送 Ajax 请求,服务端返回⼀个 json,该 json 包含了所有要更新的模块的 hash 值,获取到更新列表后,该模块再次通过 jsonp 请求,获取到最新的模块代码。这就是上图中 7、8、9 步骤。
7. ⽽第 10 步是决定 HMR 成功与否的关键步骤,在该步骤中,HotModulePlugin 将会对新旧模块进⾏对⽐,决定是否更新模块,在决定更新模块后,检查模块之间的依赖关系,更新模块的同时更新模块间的依赖引⽤。
8. 最后⼀步,当 HMR 失败后,回退到 live reload 操作,也就是进⾏浏览器刷新来获取最新打包代码。
详细原理解析来源于知乎饿了么前端Webpack HMR 原理解析
如何⽤webpack来优化前端性能?
⽤webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运⾏快速⾼效。压缩代码:删除多余的代码、注释、简化代码的写法等等⽅式。可以利⽤webpack
的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS⽂件, 利⽤ cssnano (css-loader?minimize)来压缩css
利⽤CDN加速: 在构建过程中,将引⽤的静态资源路径修改为CDN上对应的路径。可以利⽤webpack对于 output 参数和各loader的 publicPath 参数来修改资源路径
Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。可以通过在启动webpack时追加参数 --optimize-minimize 来实现
Code Splitting: 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存
提取公共第三⽅库: SplitChunksPlugin插件来进⾏公共模块抽取,利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码
详解可以参照前端性能优化-加载
如何提⾼webpack的打包速度?
happypack: 利⽤进程并⾏编译loader,利⽤缓存来使得 rebuild 更快,遗憾的是作者表示已经不会继续开发此项⽬,类似的替代者是thread-loader
外部扩展(externals): 将不怎么需要更新的第三⽅库脱离webpack打包,不被打⼊bundle中,从⽽减少打包时间,⽐如jQuery⽤script标签引⼊
dll: 采⽤webpack的 DllPlugin 和 DllReferencePlugin 引⼊dll,让⼀些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间
利⽤缓存: webpack.cache 、babel-loader.cacheDirectory、 HappyPack.cache 都可以利⽤缓存提⾼rebuild效率
缩⼩⽂件搜索范围: ⽐如babel-loader插件,如果你的⽂件仅存在于src中,那么可以 include: path.resolve( dirname, ‘src’) ,当然绝⼤多数情况下这种操作的提升有限,除⾮不⼩⼼build了node_modules⽂件
实战⽂章推荐使⽤webpack4提升180%编译速度 Tool
如何提⾼webpack的构建速度?
- 多⼊⼝情况下,使⽤ CommonsChunkPlugin 来提取公共代码
- 通过 externals 配置来提取常⽤库
- 利⽤ DllPlugin 和 DllReferencePlugin 预编译资源模块 通过 DllPlugin 来对那些我们引⽤但是绝对不会修改的npm 包来进⾏预编译,再通过 DllReferencePlugin 将预编译的模块加载进来。
- 使⽤ Happypack 实现多线程加速编译
- 使⽤ webpack-uglify-parallel 来提升 uglifyPlugin 的压缩速度。 原理上 webpack-uglify-parallel 采⽤了多核并⾏压缩来提升压缩速度
- 使⽤ Tree-shaking 和 Scope Hoisting 来剔除多余代码
怎么配置单⻚应⽤?怎么配置多⻚应⽤?
单⻚应⽤可以理解为webpack的标准模式,直接在 entry 中指定单⻚应⽤的⼊⼝即可,这⾥不再赘述
多⻚应⽤的话,可以使⽤webpack的 AutoWebPlugin 来完成简单⾃动化的构建,但是前提是项⽬的⽬录结构必须遵守他预设的规范。 多⻚应⽤中要注意的是:
每个⻚⾯都有公共的代码,可以将这些代码抽离出来,避免重复的加载。⽐如,每个⻚⾯都引⽤了同⼀套css样式表
随着业务的不断扩展,⻚⾯可能会不断的追加,所以⼀定要让⼊⼝的配置⾜够灵活,避免每次添加新⻚⾯还需要修改构建配置
算法⾯试题
算法相关的题在前端⾯试中的⽐重越来越⾼,当然最有效的⽅法是去LeetCode上刷题,关于JavaScript版的LeetCode解题思路可以参考此项⽬leetcode题解,记录⾃⼰的leetcode解题之路
如何分析时间复杂度?
当问题规模即要处理的数据增⻓时,基本操作要重复执⾏的次数必定也会增⻓,那么我们关⼼地是这个执⾏次数以什么样的数量级增⻓。
我们⽤⼤O表示法表示⼀下常⻅的时间复杂度量级:
常数阶O(1) 线性阶O(n) 对数阶O(logn) 线性对数阶O(nlogn) 平⽅阶O(n²) 当然还有指数阶和阶乘阶这种⾮常极端的复杂度量级,我们就不讨论了。
O(1)
传说中的常数阶的复杂度,这种复杂度⽆论数据规模n如何增⻓,计算时间是不变的。举⼀个简单的例⼦:
不管n如何增⻓,都不会影响到这个函数的计算时间,因此这个代码的时间复杂度都是O(1)。
O(n)
线性复杂度,随着数据规模n的增⻓,计算时间也会随着n线性增⻓。典型的O(n)的例⼦就是线性查找。
线性查找的时间消化与输⼊的数组数量n成⼀个线性⽐例,随着n规模的增⼤,时间也会线性增⻓。
O(logn)
对数复杂度,随着问题规模n的增⻓,计算时间也会随着n对数级增⻓。典型的例⼦是⼆分查找法。
在⼆分查找法的代码中,通过while循环,成 2 倍数的缩减搜索范围,也就是说需要经过 log2^n 次即可跳出循环。
事实上在实际项⽬中, O(logn) 是⼀个⾮常好的时间复杂度,⽐如当 n=100 的数据规模时,⼆分查找只需要7次,线性查找需要100次,这对于计算机⽽⾔差距不⼤,但是当有10亿的数据规模的时候,⼆分查找依然只需要30次,⽽线性查找需要惊⼈的10亿次, O(logn) 时间复杂度的算法随着数据规模的增⼤,它的优势就越明显。
O(nlogn)
线性对数复杂度,随着数据规模n的增⻓,计算时间也会随着n呈线性对数级增⻓。这其中典型代表就是归并排序,我们会在对应⼩节详细分析它的复杂度。
O(n²)
平⽅级复杂度,典型情况是当存在双重循环的时候,即把 O(n) 的代码再嵌套循环⼀遍,它的时间复杂度就是 O(n²)
了,代表应⽤是冒泡排序算法。
排序算法
排序算法有很多种,我们只讲最具代表性的⼏种算法: 冒泡排序、希尔排序、归并排序、快速排序
排序算法主体内容采⽤的是⼗⼤经典排序算法总结(JavaScript描述),更详细的内容可以移步,因为作者的内容与教科书上的内容有较⼤冲突,因此我们重写了快速排序部分的内容,以教科书为准,因此建议重点读⼀下本⽂的快速排序部分.
冒泡排序(Bubble Sort)
实现思路:
- ⽐较相邻的元素。如果第⼀个⽐第⼆个⼤,就交换他们两个。
- 对每⼀对相邻元素作同样的⼯作,从开始第⼀对到结尾的最后⼀对。这步做完后,最后的元素会是最⼤的数。
- 针对所有的元素重复以上的步骤,除了最后⼀个。
- 持续每次对越来越少的元素重复上⾯的步骤,直到没有任何⼀对数字需要⽐较。实现:
改进1: 设置⼀标志性变量pos,⽤于记录每趟排序中最后⼀次进⾏交换的位置。由于pos位置之后的记录均已交换到位,故在进⾏下⼀趟排序时只要扫描到pos位置即可。
改进2: 传统冒泡排序中每⼀趟排序操作只能找到⼀个最⼤值或最⼩值,我们考虑利⽤在每趟排序中进⾏正向和反向两遍冒泡的⽅法⼀次可以得到两个最终值(最⼤者和最⼩者) , 从⽽使排序趟数⼏乎减少了⼀半。
动画:
希尔排序(Shell Sort)
1959年Shell发明; 第⼀个突破O(n^2)的排序算法;是简单插⼊排序的改进版;它与插⼊排序的不同之处在于, 它会优先⽐较距离较远的元素。希尔排序⼜叫缩⼩增量排序
算法简介
希尔排序的核⼼在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第4版》的合著者Robert Sedgewick提出的。
算法描述和实现
先将整个待排序的记录序列分割成为若⼲⼦序列分别进⾏直接插⼊排序,具体算法描述:
- 选择⼀个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
- 按增量序列个数k,对序列进⾏k 趟排序;
- 每趟排序,根据对应的增量ti,将待排序列分割成若⼲⻓度为m 的⼦序列,分别对各⼦表进⾏直接插⼊排序。仅增量因⼦为1 时,整个序列作为⼀个表来处理,表⻓度即为整个序列的⻓度。
Javascript代码实现:
希尔排序图示(图⽚来源⽹络):
算法分析
最佳情况:T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) =O(nlog n)
归并排序(Merge Sort)
和选择排序⼀样,归并排序的性能不受输⼊数据的影响,但表现⽐选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。
算法简介
归并排序是建⽴在归并操作上的⼀种有效的排序算法。该算法是采⽤分治法(Divide and Conquer)的⼀个⾮常典型的应⽤。归并排序是⼀种稳定的排序⽅法。将已有序的⼦序列合并,得到完全有序的序列;即先使每个⼦序列有序,再使⼦序列段间有序。若将两个有序表合并成⼀个有序表,称为2-路归并。
算法描述和实现
具体算法描述如下:
- 把⻓度为n的输⼊序列分成两个⻓度为n/2的⼦序列;
- 对这两个⼦序列分别采⽤归并排序;
- 将两个排序好的⼦序列合并成⼀个最终的排序序列。
Javscript代码实现:
归并排序动图演示:
算法分析
最佳情况:T(n) = O(n)
最差情况:T(n) = O(nlogn)
平均情况:T(n) = O(nlogn)
快速排序(Quick Sort) 算法简介
快速排序的基本思想:通过⼀趟排序将待排记录分隔成独⽴的两部分,其中⼀部分记录的关键字均⽐另⼀部分的关键字
⼩,则可分别对这两部分记录继续进⾏排序,以达到整个序列有序。
算法描述和实现
- 从数组中选择中间⼀项作为主元;
- 创建两个指针,左边⼀个指向数组的第⼀项,右边指向数组最后⼀项。移动左指针直到我们找到⼀个⽐主元⼤的元 素,接着,移动右指针直到找到⼀个⽐主元⼩的元素。然后交换它们,重复这个过程,直到左指针超过了右指针。这个过程是的⽐主元⼩的值都排在了主元之前,⽽⽐主元⼤的值都排在了主元之后,这⼀步叫划分操作。
- 接着,算法对划分的⼩数组(较主元⼩的值组成的⼦数组,以及较主元⼤的值组成的⼦数组)重复之前的两个步骤, 直⾄数组以完全排序。
算法分析
最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(nlogn)
查找算法
⼆分查找法算法简介
折半查找算法要求查找表的数据是线性结构存储,还要求查找表中的顺序是由⼩到⼤排序(由⼤到⼩排序)
算法思路及实现
- ⾸先设两个指针,low和height,表示最低索引和最⾼索引
- 然后取中间位置索引middle,判断middle处的值是否与所要查找的数相同,相同则结束查找,middle处的值⽐所要查找的值⼩就把low设为middle+1,如果middle处的值⽐所要查找的值⼤就把height设为middle-1
- 然后再新区间继续查到,直到找到或者low>height找不到所要查找的值结束查找
算法分析
最佳情况:T(n) = O(logn) 最差情况:T(n) = O(logn) 平均情况:T(n) = O(logn)
线性查找
算法简介及实现
线性查找很简单,只需要进⾏简单的遍历即可.
算法分析
最佳情况:T(n) = O(n) 最差情况:T(n) = O(n) 平均情况:T(n) = O(n)
字符串类⾯试题
解析 URL Params 为对象
模板引擎实现
转化为驼峰命名
查找字符串中出现最多的字符和个数
例: abbcccddddd -> 字符最多的是d,出现了5次
字符串查找
请使⽤最基本的遍历来实现判断字符串 a 是否被包含在字符串 b 中,并返回第⼀次出现的位置(找不到返回 -1)。
实现千位分隔符
正则表达式(运⽤了正则的前向声明和反前向声明):
判断是否是电话号码
验证是否是邮箱
验证是否是身份证
参考:
前端⾯试遇到的算法题
JavaScript笔试部分
实现防抖函数(debounce)
防抖函数原理:在事件被触发n秒后再执⾏回调,如果在这n秒内⼜被触发,则重新计时。那么与节流函数的区别直接看这个动画实现即可。
⼿写简化版:
适⽤场景:
按钮提交场景:防⽌多次提交按钮,只执⾏最后提交的⼀次
服务端验证场景:表单验证需要服务端配合,只执⾏⼀段连续的输⼊事件的最后⼀次,还有搜索联想词功能类似
⽣存环境请⽤lodash.debounce
实现节流函数(throttle)
防抖函数原理:规定在⼀个单位时间内,只能触发⼀次函数。如果这个单位时间内触发多次函数,只有⼀次⽣效。
// ⼿写简化版
适⽤场景:
拖拽场景:固定时间内只执⾏⼀次,防⽌超⾼频次触发位置变动缩放场景:监控浏览器resize
动画场景:避免短时间内多次触发动画引起性能问题
深克隆(deepclone)
简单版:
局限性:
- 他⽆法实现对函数 、RegExp等特殊对象的克隆
- 会抛弃对象的constructor,所有的构造函数会指向Object
- 对象有循环引⽤,会报错
⾯试版:
flag = typeString === “[object Array]”; break;
case “Date”:
flag = typeString === “[object Date]”; break;
case “RegExp”:
flag = typeString === “[object RegExp]”; break;
default:
flag = false;
}
return flag;
};
// 处理正则
const getRegExp = re => { var flags = “”;
if (re.global) flags += “g”;
if (re.ignoreCase) flags += “i”; if (re.multiline) flags += “m”; return flags;
};
// 维护两个储存循环引⽤的数组const parents = []; const children = [];
const _clone = parent => {
if (parent === null) return null;
if (typeof parent !== “object”) return parent;
let child, proto;
if (isType(parent, “Array”)) {
// 对数组做特殊处理
child = [];
} else if (isType(parent, “RegExp”)) {
// 对正则对象做特殊处理
child = new RegExp(parent.source, getRegExp(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (isType(parent, “Date”)) {
// 对Date对象做特殊处理
child = new Date(parent.getTime());
} else {
// 处理对象原型
proto = Object.getPrototypeOf(parent);
// 利⽤Object.create切断原型链
child = Object.create(proto);
}
// 处理循环引⽤
const index = parents.indexOf(parent);
if (index != -1) {
// 如果⽗数组存在本对象,说明之前已经被引⽤过,直接返回此对象
return children[index];
}
parents.push(parent); children.push(child);
for (let i in parent) {
// 递 归
child[i] = _clone(parent[i]);
}
return child;
};
return _clone(parent);
};
局限性:
- ⼀些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map
- 另外对于确保没有循环引⽤的对象,我们可以省去对循环引⽤的特殊处理,因为这很消耗时间
原理详解实现深克隆
实现Event(event bus)
event bus既是node中各个模块的基⽯,⼜是前端组件通信的依赖⼿段之⼀,同时涉及了订阅-发布设计模式,是⾮常重要的基础。
简单版:
⾯试版:
};
// 监听名为type的事件
EventEmeitter.prototype.addListener = function(type, fn) {
// 将type事件以及对应的fn函数放⼊this._events中储存
if (!this._events.get(type)) { this._events.set(type, fn);
}
};
// 触发名为type的事件
EventEmeitter.prototype.emit = function(type, …args) { let handler;
handler = this._events.get(type); if (Array.isArray(handler)) {
// 如果是⼀个数组说明有多个监听者,需要依次此触发⾥⾯的函数
for (let i = 0; i < handler.length; i++) { if (args.length > 0) {
handler[i].apply(this, args);
} else { handler[i].call(this);
}
}
} else {
// 单个函数的情况我们直接触发即可
if (args.length > 0) { handler.apply(this, args);
} else { handler.call(this);
}
}
return true;
};
// 监听名为type的事件
EventEmeitter.prototype.addListener = function(type, fn) {
const handler = this._events.get(type); // 获取对应事件名称的函数清单
if (!handler) { this._events.set(type, fn);
} else if (handler && typeof handler === “function”) {
// 如果handler是函数说明只有⼀个监听者
this._events.set(type, [handler, fn]); // 多个监听者我们需要⽤数组储存
} else {
handler.push(fn); // 已经有多个监听者,那么直接往数组⾥push函数即可
}
};
EventEmeitter.prototype.removeListener = function(type, fn) { const handler = this._events.get(type); // 获取对应事件名称的函数清单
// 如果是函数,说明只被监听了⼀次
if (handler && typeof handler === “function”) { this._events.delete(type, fn);
} else {
let postion;
// 如果handler是数组,说明被监听多次要找到对应的函数
for (let i = 0; i < handler.length; i++) { if (handler[i] === fn) {
postion = i;
} else { postion = -1;
}
}
// 如果找到匹配的函数,从数组中清除
if (postion !== -1) {
// 找到数组对应的位置,直接清除此回调
handler.splice(postion, 1);
// 如果清除后只有⼀个函数,那么取消数组,以函数形式保存
实现具体过程和思路⻅实现event
实现instanceOf
模拟new
new操作符做了这些事:
它创建了⼀个全新的对象
它会被执⾏[[Prototype]](也就是proto)链接它使this指向新创建的对象
通过new创建的每个对象将最终被[[Prototype]]链接到这个函数的prototype对象上
如果函数没有返回对象类型Object(包含Functoin, Array, Date, RegExg, Error),那么new表达式中的函数调⽤将返回该对象引⽤
实现⼀个call
call做了什么:
将函数设为对象的属性执⾏&删除这个函数
指定this到函数并传⼊给定参数执⾏函数如果不传⼊参数,默认指向为 window
具体实现参考JavaScript深⼊之call和apply的模拟实现
实现apply⽅法
apply原理与call很相似,不多赘述
实现bind
实现bind要做什么
返回⼀个函数,绑定this,传递预置参数
bind返回的函数可以作为构造函数使⽤。故作为构造函数时应使得this失效,但是传⼊的参数依然有效
详解请移步JavaScript深⼊之bind的模拟实现 #12
模拟Object.create
Object.create()⽅法创建⼀个新对象,使⽤现有的对象来提供新创建的对象的proto。
实现类的继承
类的继承在⼏年前是重点内容,有n种继承⽅式各有优劣,es6普及后越来越不重要,那么多种写法有点『回字有四样写法』的意思,如果还想深⼊理解的去看红宝书即可,我们⽬前只实现⼀种最理想的继承⽅式。
实现JSON.parse
此⽅法属于⿊魔法,极易容易被xss攻击,还有⼀种 new Function ⼤同⼩异。简单的教程看这个半⼩时实现⼀个 JSON 解析器
实现Promise
我很早之前实现过⼀版,⽽且注释很多,但是居然找不到了,这是在⽹络上找了⼀版带注释的,⽬测没有⼤问题, 具体过程可以看这篇史上最易读懂的 Promise/A+ 完全实现
}.bind(this),
// onRejected function (reason2) {
if (thenAlreadyCalledOrThrow) return thenAlreadyCalledOrThrow = true resolveOrReject.bind(this, ‘rejected’, reason2)()
}.bind(this)
)
} else {
// 拥有then 但是then不是⼀个函数 所以也不是thenable resolveOrReject.bind(this, ‘resolved’, value)()
}
} catch (e) {
if (thenAlreadyCalledOrThrow) return thenAlreadyCalledOrThrow = true resolveOrReject.bind(this, ‘rejected’, e)()
}
} else {
// 基本类型 直接返回
resolveOrReject.bind(this, ‘resolved’, value)()
}
}
function resolveOrReject (status, data) { if (this.status !== ‘pending’) return this.status = status
this.data = data
if (status === ‘resolved’) {
for (var i = 0; i < this.resolveList.length; ++i) { this.resolveListi
}
} else {
for (i = 0; i < this.rejectList.length; ++i) { this.rejectListi
}
}
}
function Promise (executor) {
if (!(this instanceof Promise)) {
throw Error(‘Promise can not be called without new !’)
}
if (typeof executor !== ‘function’) {
// ⾮标准 但与Chrome⾕歌保持⼀致
throw TypeError(‘Promise resolver ’ + executor + ’ is not a function’)
}
this.status = ‘pending’ this.resolveList = [] this.rejectList = []
try {
executor(tryToResolve.bind(this), resolveOrReject.bind(this, ‘rejected’))
} catch (e) {
resolveOrReject.bind(this, ‘rejected’, e)()
}
}
Promise.prototype.then = function (onFullfilled, onRejected) {
// 返回值穿透以及错误穿透, 注意错误穿透⽤的是throw⽽不是return,否则的话
// 这个then返回的promise状态将变成resolved即接下来的then中的onFullfilled
// 会被调⽤, 然⽽我们想要调⽤的是onRejected
if (typeof onFullfilled !== ‘function’) { onFullfilled = function (data) {
return data
}
}
if (typeof onRejected !== ‘function’) { onRejected = function (reason) {
throw reason
}
}
var executor = function (resolve, reject) { setTimeout(function () {
try {
// 拿到对应的handle函数处理this.data
// 并以此为依据解析这个新的Promise
var value = this.status === ‘resolved’
? onFullfilled(this.data)
: onRejected(this.data) resolve(value)
} catch (e) { reject(e)
}
}.bind(this))
}
// then 接受两个函数返回⼀个新的Promise
// then ⾃身的执⾏永远异步与onFullfilled/onRejected的执⾏
if (this.status !== ‘pending’) {
return new Promise(executor.bind(this))
} else {
// pending
return new Promise(function (resolve, reject) { this.resolveList.push(executor.bind(this, resolve, reject)) this.rejectList.push(executor.bind(this, resolve, reject))
}.bind(this))
}
}
// for prmise A+ test
Promise.deferred = Promise.defer = function () { var dfd = {}
dfd.promise = new Promise(function (resolve, reject) { dfd.resolve = resolve
dfd.reject = reject
})
return dfd
}
// for prmise A+ test
if (typeof module !== ‘undefined’) { module.exports = Promise
}
return Promise
})()
PromisePolyfill.all = function (promises) { return new Promise((resolve, reject) => {
const result = [] let cnt = 0
for (let i = 0; i < promises.length; ++i) { promises[i].then(value => {
cnt++
result[i] = value
if (cnt === promises.length) resolve(result)
}, reject)
}
})
}
PromisePolyfill.race = function (promises) { return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; ++i) {
基础篇
1、列举Java和JavaScript之间的区别?
Java是一门十分完整、成熟的编程语言。相比之下,JavaScript是一个可以被引入HTML页面的编程语言。这两种语言并不完全相互依赖,而是针对不同的意图而设计的。 Java是一种面向对象编程(OOPS)或结构化编程语言,类似的如C ++或C,而JavaScript是客户端脚本语言,它被称为非结构化编程。
2、什么是负无穷大?
负无穷大是JavaScript中的一个数字,可以通过将负数除以零来得到。
3、什么是未声明和未定义的变量?
未声明的变量是程序中不存在且未声明的变量。如果程序尝试读取未声明变量的值,则会遇到运行时错误。未定义的变量是在程序中声明但尚未给出任何值的变量。如果程序尝试读取未定义变量的值,则返回未定义的值。
4、什么是全局变量?这些变量如何声明,使用全局变量有哪些问题?
全局变量是整个代码长度可用的变量,也就是说这些变量没有任何作用域。var关键字用于声明局部变量或对象。如果省略var关键字,则声明一个全局变量。
例:// Declare a global globalVariable = “Test”;
使用全局变量所面临的问题是本地和全局变量名称的冲突。此外,很难调试
5、解释JavaScript中定时器的工作?如果有,也可以说明使用定时器的缺点?
定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码。这通过使用函数setTimeout,setInterval和clearInterval来完成。
setTimeout(function,delay)函数用于启动在所述延迟之后调用特定功能的定时器。
setInterval(function,delay)函数用于在提到的延迟中重复执行给定的功能,只有在取消时才停止。
clearInterval(id)函数指示定时器停止。
定时器在一个线程内运行,因此事件可能需要排队等待执行。
6、什么是=运算符?
=被称为严格等式运算符,当两个操作数具有相同的值而没有任何类型转换时,该运算符返回true。
7、说明如何使用JavaScript提交表单?
要使用JavaScript提交表单,请使用
document.form [0] .submit();
8、说明“”和“=”之间的区别?
“”仅检查值相等,而“=”是一个更严格的等式判定,如果两个变量的值或类型不同,则返回false。
9、3 + 2 +“7”的结果是什么?
由于3和2是整数,它们将直接相加。由于7是一个字符串,它将会被直接连接,所以结果将是57。
10、Javascript中的NULL是什么意思?
NULL用于表示无值或无对象。它意味着没有对象或空字符串,没有有效的布尔值,没有数值和数组对象。
11、什么是JavaScript Cookie?
Cookie是用来存储计算机中的小型测试文件,当用户访问网站以存储他们需要的信息时,它将被创建。
12、在JavaScript中使用innerHTML的缺点是什么?
如果在JavaScript中使用innerHTML,缺点是:内容随处可见;不能像“追加到innerHTML”一样使用;即使你使用+ = like“innerHTML = innerHTML +‘html’”旧的内容仍然会被html替换;整个innerHTML内容被重新解析并构建成元素,因此它的速度要慢得多;innerHTML不提供验证,因此我们可能会在文档中插入有效的和破坏性的HTML并将其中断。
13、break和continue语句的作用?
Break语句从当前循环中退出。
continue语句继续下一个循环语句。
14、JavaScript中不同类型的错误有几种?
有三种类型的错误:
Load time errors:该错误发生于加载网页时,例如出现语法错误等状况,称为加载时间错误,并且会动态生成错误。
Run time errors:由于在HTML语言中滥用命令而导致的错误。
15、解释window.onload和onDocumentReady?
logical Errors:这是由于在具有不同操作的函数上执行了错误逻辑而发生的错误。
在载入页面的所有信息之前,不运行onload函数。这导致在执行任何代码之前会出现延迟。onDocumentReady在加载DOM之后加载代码。这允许早期的代码操纵。
16、解释延迟脚本在JavaScript中的作用?
默认情况下,在页面加载期间,HTML代码的解析将暂停,直到脚本停止执行。这意味着,如果服务器速度较慢或者脚本特别沉重,则会导致网页延迟。在使用Deferred时,脚本会延迟执行直到HTML解析器运行。这减少了网页加载时间,并且它们的显示速度更快。
17、如何在不支持JavaScript的旧浏览器中隐藏JavaScript代码
在
23、介绍一下你了解的CSS3?
Css3新增了一些属性,比如:
border-radius,可以用来给div加圆角,
box-shadow 用来给盒子加阴影。
text-shadow用来给文字加阴影。
Box-sizing用来重新定义盒子模型:
content-box(w3c标准的盒子模型,盒子的宽度就是内容的宽度,是默认的);
border-box(是ie的盒子模型,盒子的宽度等于内容+padding+border);
linear-gradient:用来做渐变色。
24、绑定事件:
主流浏览器.
addEventListener // .removeEventListener
IE8以及以下:.
attachEvent //.detachEvent
25、常见内存泄露的原因?
全局变量引起的内存泄露
闭包引起的内存泄露:慎用闭包
dom清空或删除时,事件未清除导致的内存泄漏
循环引用带来的内存泄露
26、浏览器加载资源(html、图片、js、css)的顺序
html 图片 css js
27、说一下ie,谷歌和火狐的兼容性问题?
常见的兼容性问题大都出现在ie8以下的浏览器,比如ie6的双边距问题,ie6的3像素问题,盒子模型的计算宽度不一样。Ie6,7中li底部有三像素问题增加浮动解决。
Ie一般用css前缀过滤对不同版本的浏览器兼容实现样式。其他的部分就是一些css3新增的属性,各个浏览器相互不兼容,需要加前缀:
-webkit- -moz- -o- -ms-
Js部分:
Firefox中没有removenode方法。node.parentNode.removeChild(node)
绑定事件:
主流浏览器 .addEventListener//.removeEventListener
Ie8以及以下 .attachEvent//.detachEvent
28、http请求流程
1)、web服务器和浏览器服务器 建立连接
2)、web服务器向浏览器服务器 发送命令
3)、web服务器向浏览器服务器 发送请求头
4)、浏览器服务器向web服务器 应答
5)、浏览器服务器向web服务器 发送应答头
6)、web服务器向浏览器服务器 发送数据
7)、web服务器向浏览器服务器 断开连接
29、js 闭包的作用
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
30、jsonp原理
JSONP (json with padding) 通过javascript callback 实现跨域访问的一种机制,由于同源策略的机制,XMLhttpRequest只允许访问同域名 同协议 同端口下的资源,所以使用 带有src 属性的标签 能够使浏览器返回数据,从而解决跨域请求问题
31、js中使用typeof能得到哪些类型?
undefined、string、number、boolean、object、function
32、描述new一个对象的过程
1.创建一个新对象
2.this指向这个新对象
3.执行代码,即对this赋值
4.返回this
33、前端使用异步的场景有哪些
1)、setTimeout、setInverval
2)、ajax请求、动态加载
3)、事件请求
(特点:都需要等待,由js是单线程语言所决定)
34、浏览器从输入网址到页面展示的过程之间发生了什么?
浏览器向DNS服务器查找输入URL对应的IP地址
DNS服务器返回网站的IP地址
DNS服务器根据IP地址与目标web服务器在80端口上建立TCP连接
浏览器获取请求页面的html代码
浏览器在显示的窗口内渲染html
浏览器窗口关闭时,终止与服务器的连接
35、localstorage存放在哪里?不同浏览器之间可以公用吗?
localStorage保存的数据,一般情况下是永久保存的,也就是说只要采用localstorage保存信息,数据便一直存储在用户的客户端中。即使用户关闭当前web浏览器后重新启动,数据依然存在。直到用户或程序明确制定删除,数据的生命周期才会结束。
在安全性方面,localstorage是域内安全的,即localstorage是基于域的。任何在该域内的所有页面,都可以访问localstorage数据。但仍然存在一个问题,就是各个浏览器厂商的浏览器之间的数据是各自独立的。也就是说,如果在firefox中使用localstorage存储一组数据,在chrome浏览器下是无法读取的。同样,由于localstorage数据是保存在用户的设备中的,因此同一个应用程序在不同设备上保存的数据是不同的。
36、Flex布局与bootstrap的区别?
在Bootstrap中采用12栅格的布局,12份随意分配,但是不能解决5等分,7等分的问题。所以flex布局来协助。
Flex比Bootstrap的布局适应性更强,因为flex是基于灵活布局,而Bootstrap是自定义宽度布局,当删除元素时这些显得尤为明显。
Flex布局和Bootstrap两者相同的设计理念
内部的孩子节点无margin,元素之间的空隙用padding和border进行间隔,以及box-sizing:bording-box进行宽高的界定。
两者都完美适配手机
37、说出几种IE6 BUG的解决方法
1)、双边距Bug,由float所引起,通过使用display解决
2)、3像素问题,由使用float引起,使用display:inline -3px;解决
3)、超链接hover,点击后失效,使用正确的书写顺序:link visited hover active
4)、z-index问题,给父级添加position:relative
5)、png透明,使用js代码进行修改
6)、min-height最小高度,使用!important解决
7)、select在IE6下遮盖,使用iframe嵌套
8)、为什么没有办法定义1px左右宽度的宽度容器
(IE6默认的行高造成的,使用overflow:hidden;zoom:0.08;line-height:1px;解决)
38、什么是垃圾回收机制
当一个变量的引用次数为0的时候他在内存中就被销毁了
当一个对象数据在一定时间后,没有被使用的话,垃圾回收机制会自动把他销毁
当js代码执行完毕的时候也会自动销毁
39、iframe的优缺点?
1.优点:
解决加载缓慢的第三方内容如图标和广告等的加载问题
Security sandbox
并行加载脚本
2.的缺点
iframe会阻塞主页面的Onload事件;
即使内容为空,加载也需要时间
没有语意
40、null和undefined的区别?
undefined是一个表示"无"的原始值,转为数值时为 当声明的变量还未被初始化时,变量的默认值为null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
41、documen.write和 innerHTML的区别
document.write只能重绘整个页面
innerHTML可以重绘页面的一部分
42、你有哪些性能优化的方法?
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。
(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7)图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
43、变量声明提升
先看一段代码:
以下这段代码,因为,没有用var声明,所以出错
function testf(){
console.log(myName); //这句话会提示 myName is not definded;
}
再看一段代码:
function testf(){
var myName; //声明一个变量,没有赋值,但是经过预编译,会给该变量赋值为undefined;
console.log(myName); //这句话就显示undefined;
44、假如一个页面左边是固定的200px宽度,右边是自适应布局,如何实现?右边的宽度是如何获取的
1,左边固定宽度;右边100%,左浮动 padding-left = 左边的宽度
2,父元素:
display:flex,justify-content:center和align-items:flex-start
45、事件捕获和冒泡的区别
1)、事件捕获
捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)
2)、事件冒泡
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发、捕获和冒泡过程图
事件捕获和事件冒泡属于两个相反的过程,这里可以有一个我感觉十分恰当的比喻,当你把一个可以漂浮在水面上的物品,使劲向水里砸下去,它会首先有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后由于浮力大于物体自身的重力,物体会在到达最低点( 最具体元素)之后漂浮到水面上,这个过程相对于事件捕获是一个回溯的过程,即事件冒泡。
46、事件委托
1).什么是事件委托
本来是要注册给自己的事件,注册给了父元素.事件触发后的事情,委托给父元素执行
2.)事件委托的优点:
1.>document对象可以很快访问到,而且可以在页面生命周期的任何时点为它添加事件处理程序,(无需等待DOMContentLoaded或load事件)。换句话说,只要可单击的元素呈现在页面上,就可以立即具备适当的功能.
2.>在页面中设置事件处理程序所需的时间更少。只添加一个事件处理程序所需要的DOM引用更少,所花的时间更少.
3.>整个页面占用的内存空间更少,能够提升整体性能。
事件委托的原理 : 事件冒泡
47、字体图标和雪碧图的区别
设想一个实际场景:在一个页面为了展示,我们放置了很多独立的小图片,浏览器在显示页面的时候,就需要向服务器就会发送很多请求,来获取并加载这些小图片,但是这样的话,就会导致请求数量太多,造成资源浪费,以及访问速度变慢。
碰到这样的情况,可以使用两种方式解决这种问题:CSS雪碧图以及字体图标。但是这两种方式也都有不同的适用场景,需要根据实际需求来做取舍。
图标字体
可以缩放的矢量图标。你可以使用CSS对它们进行修改:大小,颜色,阴影等。体积特别的小。可能几百个图标才几十KB。
雪碧图
除了叫雪碧图外,它还有很多名字,css sprite, css 精灵等。原理就是将一些小图标合并到一张图片上,然后用css的背景定位来显示需要显示的部分。
48、使用闭包的注意点
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
49、闭包的优缺点是什么?
优点:
1、可以将一个变量长期驻扎在内存中;
2、避免全局变量的污染;
3、私有成员的存在。
缺点:
1、会使函数的变量被保存在内存中,内存消耗极大,会造成网页性能问题,在IE中会导致内存泄漏。
解决办法:在退出函数之前,将不使用的局部变量设置为null。
2、闭包会在父函数外部,改变父函数内部变量的值,所以如果把父函数当做对象使用,会把闭包当做它的公用方法,把内部变量当做它的私有属性,所以使用时一定要小心,不要随便改变父函数内部变量的值。一阶段常见的面试题(初稿)
50、常见浏览器兼容性问题
不同的浏览器对同一段代码解析不同导致显示效果不同的问题叫做浏览器兼容性问题。
1.双倍浮动bug
描述:块元素设置浮动后,又设置了横向的margin值,在IE6下,显示的比设置的值要大,并且是2倍关系
解决方案: 给浮动的块元素设置display:inline;
2.表单元素行高不一致
解决方案:
a) input{float:left;}
b) input{vertical-align:top|middle|bottom;}
3.图片默认有空隙
解决方案:
a) img{display:block;}
b) img{float:left;}
c) img{vertical-align:top|middle|bottom;}
4.给img添加超链接时,在某些浏览器中(如ie)会出现带有颜色的边框
解决方案:
img{border:none;} 或 img{border:0;}
5.鼠标指针bug
描述: cursor:hand; 在IE8以上浏览器不识别设置为手的形状
解决方案: cursor:pointer;
- 当设置高度较小时,IE6识别不正确
解决方案:给元素添加overflow:hidden;
7.min-height属性IE6不识别
解决方案: min-height:100px; _height:100px;
8.IE8及以下浏览器不能识别opacity属性
解决方案: filter:alpha(opactiy=数值);
51、百分比bug
描述:子元素设置宽度为50%,父元素宽度100%,在IE6下,50%加50%大于100%
解决方案:给右边浮动的元素添加clear:right;
52、市场上主流五大浏览器内核及其代表作品
1.IE浏览器(不开源,不能跨平台)
内核: Trident
2.火狐浏览器 Mozilla Firefox (开源,跨平台)
内核: Gecko
3.谷歌浏览器 Google Chrome(开源,跨平台)
内核: Webkit —> Blink
4.苹果浏览器 Safari (开源,跨平台)
内核: Webkit
5.欧朋 Opera (开源,跨平台,曾被认为是世界上运行最快的浏览器)
内核: Presto —> Webkit —> Blink
注:国内大部分浏览器都是IE+Chrome双内核
大部分手机浏览器都是webkit内核
53、BFC
1.概念
BFC—block formatting context (中文译为块级格式化上下文)
2.如何触发BFC
a) 设置float除none以外的其他值(left或right)
b) 设置overflow除visible以外的其他值(hidden,scroll,auto)
c) 设置display的属性值为: table-cell,table-caption,inline-block,flex;
d) 设置position的属性值为absolute和fixed
3.BFC特性
a) 浮动元素会被父元素计算高度(父元素触发了BFC)
b) 子元素的margin值不会传递给父级(父元素触发了BFC)
c) 上下margin值不会重叠(给其中一个元素增加一个父级,并触发BFC)
d) 非浮动元素不会覆盖浮动元素位置(非浮动元素触发了BFC)
54、渐进增强和优雅降级
1.渐进增强(由低到高)
刚开始针对低版本浏览器构建页面的基本功能,然后针对高版本浏览器进行交互效果的添加,达到更好的用户体验
2.优雅降级(由高到低)
刚开始就构建网站的完整功能,然后针对各版本浏览器进行调试和修复。
渐进增强
eg1: .box{
-webkit-transition:all 1s;
-moz-transition:all 1s;
-o-transition:all 1s;
-ms-transition:all 1s;
transition:all 1s;
}
优雅降级
eg2: .box{
transition:all 1s;
-webkit-transition:all 1s;
-moz-transition:all 1s;
-o-transition:all 1s;
-ms-transition:all 1s;
}
55、常见移动端布局方案
1.百分比布局(流式布局)
特点:不管分辨率怎么变,顶部和底部的高度和位置都不变,文字流式,控件弹性,图片等比缩放
典型案例:拉勾网
2.等比例缩放布局(rem布局)
特点:使用rem为主要单位进行页面布局,很好的实现了在不同设备上页面等比例缩放
3.混合布局
特点:将多种单位(px,rem,vw等),多种布局方式(flex布局,圣杯布局)融合在一起实现移动端的屏幕适配的方案
56、移动端相关单位
1.px
像素,相对于屏幕分辨率而言
2.em
相对于父元素字体大小的单位
默认情况下: 1em=16px=100%=12pt=medium
3.rem
相对于根元素字体大小的单位
注:我们在移动端一般采用rem布局,因为根元素字体大小固定,而父元素字体大小不固定,经常发生变化,容易造成逐层的连锁反应
57、link和@import引入外部样式的区别
1.老祖宗区别
link是html标签,除了可以引入css文件,还可以引入其他文件
@import属于css范畴,只能引入css文件。
2.加载顺序不同
link引入的css文件和页面同时加载,@import引入的css文件在页面加载完成后载入
3.浏览器支持不同
link引入css文件无兼容性问题,@import是css2.1提出的,低版本浏览器不支持
4.是否支持js控制DOM
link属于html标签,支持js控制DOM改变样式,@import不支持
58、rgba模式和opacity的区别
Rgba模式是给元素的背景添加一定的透明度,容器内的图片和文字不会跟随透明;
Opacity是给容器添加一定的透明度,容器内的文字和图片会跟随透明
语法:background:rgba(r,g,b,a); a代表透明度 取值范围为0~1
59、http协议属于七层协议中的哪一层,下一层是什么
七层结构:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
TCP 属于传输层;
HTTP 属于应用层。
HTTP的下一层是表现层
60、sessionStorage和localstorage能跨域拿到吗?比如我在www.baidu.com设置的值能在m.baidu.com能拿到吗?为什么?
localStorage会跟cookie一样受到跨域的限制,会被document.domain影响
cookie、sessionStorage、LocalStorage不能跨域,不能跨浏览器, cookie、LocalStorage跨域需要特殊处理。
61、new操作符具体干了什么呢?
1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2)属性和方法被加入到 this 引用的对象中。
3)新创建的对象由 this 所引用,并且最后隐式的返回 this 。
62、form中的input可以设置为readonly和disable,请问2者有什么区别?
readonly不可编辑,但可以选择和复制;值可以传递到后台
disabled不能编辑,不能复制,不能选择;值不可以传递到后台
63、用CSS实现一个三角形
64、bind,call和apply的区别
1、相同点:
三个函数都会改变this的指向(调用这三个函数的函数内部的this)
2、不同点:
1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
65、let和const是什么意思
1、let声明的变量
1)、let声明的变量是块级作用域(所在花括号里),var是函数作用域和全局作用域
注意:let是可以定义全局变量,局部变量,块级作用域的变量。
2)、let声明的变量不会声明提升,var会声明提升
3)、从代码的写法上,let不能声明同名的变量,var可以。
2、const声明的变量
1)、const修饰的变量是只读,不能修改的,即是常量
2)、const修饰的是直接指向(修饰)的内存
66、请问parseInt(),parseFloat(),Number()的区别?
1、parseInt()字符串转换成整型,parseFloat()字符串转换成浮点型,Number()字符串转换成数字型;
2、Number():看的是整体,只要字符串内的内容不是合法的数字,则结果为NaN;否则,就会正常转换为数字类型。
parseInt()和parseFloat()的转换规则比较接近(类似);
从前朝后,如果第一个字符是非数字,那么,结果为NaN;如果第一个字符是数字:
1)、parseInt():如果遇到小数点或者其它非数字字符或结尾,那么就把前面的内容正常转换为数字
2)、parseFloat():如果遇到第二个小数点或者其它非数字字符或结尾,那么就把前面的内容正常转换为数字
67、使用console和alert的区别?
- alert:
(1)对代码运行有阻塞作用,在弹出框输出,不点击确定,后续代码无法继续执行
(2)只能输出string,如果输出的是对象会自动调用toString()方法
(3)只能接收一个参数; - console:
(1)对代码运行无阻塞作用,在打印台输出
(2)能打印任何类型的数据
(3)可接收多个参数,同时打印多个数据;
68、标准盒模型和怪异盒模型的区别?
标准盒模型:总宽度=width+左右padding+左右border
总高度=height+上下height+上下border
怪异盒模型:总宽度=width(包含了padding和border)
总宽度=height(包含了padding和border)
盒模型转换语法:box-sizing:content-box(标准盒模型)/boder-box(怪异盒模型)
69、请说出三种减少页面加载时间的方法?
(1)减少http请求(合并文件、合并图片)
(2)优化图片文件,减小其尺寸
(3)图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
(4)压缩Javascript、CSS代码
(5)元素标明高度和宽度
(6)网址后面加上“/”
70、怎么清空数组?怎么去除数组重复的元素?
1、清空数组:
(1)给数组的length赋值为0,arr.length=0;
(2)给数组重新赋值为【】,arr=[ ];
(3)arr.splice(0,arr.length)
2、去重:
1)第一种方法:
function method01(){
var arr=[]; //定义一个临时数组
for(var i = 0; i < this.length; i++){ //循环遍历当前数组
//判断当前数组下标为i的元素是否已经保存到临时数组
//如果已保存,则跳过,否则将此元素保存到临时数组中
if(arr.indexOf(this[i]) == -1){
arr.push(this[i]);
}
}
return arr;
}
2)第二种方法:
function method02(){
//直接定义结果数组
var arr=[ ] ;
for(var i = 1; i < this.length; i++){ //从数组第二项开始循环遍历此数组
//对元素进行判断:
//如果数组当前元素在此数组中第一次出现的位置不是i
//那么我们可以判断第i项元素是重复的,否则直接存入结果数组
if(this.indexOf(this[i]) == i){
arr.push(this[i]);
}
}
return arr;
}
71、jQuery源码中值得借鉴的?
1.使用模块化思想,模块间保持独立,不会导致多个开发人员合作市产生冲突
2.在设计程序时,要结构清晰,高内聚,低耦合
3、利用多态的方式,实现方法 的重载,提高代码的复用率
4.jQuery的链式调用以及回溯
5.jQuery.fn.extend与jQuery.extend方法来实现扩展静态方法或实例方法
72、WEB安全——你所了解到的Web攻击技术
1.XSS攻击
2.CSFR攻击
(跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。)
3.网络劫持攻击
4.控制台注入代码
5.钓鱼
如何防止XSS攻击
1.将前端输出数据都进行转义
2.将输出的字符串的\进行转义
3.从url中获取的信息,防止方法是由后端获取,在前端进行输出
4.使用cookie的HttpOnly属性,保护好cookie
73、this指针问题
this:是函数的内置对象,只能出现在函数内部。
this是这个的意思,是代名词。代表谁,需要看场景
1、当this所在函数是事件处理函数时,this是事件源
2、当this所在函数是构造函数时,this是new出来的对象
3、当this所在函数是类的方法时,this是调用函数的对象(函数的所属对象)。
4、当this所在函数普通函数(不是以上情况),this是window对象。
74、position有几种?有什么区别?哪几个是脱离文档流的?
1.static(静态)默认值,不受top、bottom、left、right属性影响,不脱离文档流的布局
2.Relative(相对):相对定位,受top、bottom、left、right属性影响,只改变自身的位置, 不脱离文档流的布局
3.Absolute(绝对):绝对定位,定位的起始位置为最近的父元素(position不为static), 脱离文档流的布局
4.fixed(固定):固定定位,元素的位置相对于浏览器窗口是固定位置。脱离文档流的布局
75、左边固定,右边自适应的布局
76、百度移动端首页秒开是如何做到的?
- 静态文件放置
- 缓存
- 外链
- 缓存DOM
- 使用icontfont
- 卡片的异步加载与缓存
- 不在首屏的就要异步化
- 少量静态文件的域名
77、项目测试没有问题。但是放到线上就有问题了,你是怎么分析的?
后端的原因:后端接口,后端服务器
域名,IP和路径问题
网络环境问题
线上库,框架,工作的版本和本地不一致的问题
线上和本地数据资源不一致问题
程序BUG
78、懒加载的实现原理
意义:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数
实现原理:先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用
实现方式: - 第一种纯粹的延迟加载,使用setTimeout或setInterval进行加载延迟
- 第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。
第三种是可视区加载,既仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到的某图片前一定距离便开始加载,这样能保证用户拉下时正好能看图片
79、javascript对象的几种创建方式
1,工厂模式
2,构造函数模式
3,原型模式
4,混合构造函数和原型模式
5,动态原型模式
6,寄生构造函数模式
7,稳妥构造函数模式
80、javascript继承的6种方法
1,原型链继承
2,借用构造函数继承
3,组合继承(原型+借用构造)
4,原型式继承
5,寄生式继承
6,寄生组合式继承
81、HTTP与HTTPS的区别
1、HTTP是超文本传输协议,信息是明文传输,HTTPS是具有安全性的SSL加密传输协议。
2、HTTPS协议需要申请证书,一般免费证书少,因而需要一定费用。
3、HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样。前者是80,后者是443。
82、移动端(Android IOS)怎么做好用户体验?
1.简化导航,帮助用户尽快的找到想要的内容。
2.多考虑手势与触感,帮助用户更快更高效地完成交互。
3.创造对话,增加用户交互感。
4.动画化,能够吸引用户关注,并且能够帮助用户展示如何更好的设计和交互。
5.善用新用户引导流程和表单,引导用户熟悉其功能。
83、v-show和v-if有什么区别?
1.本质:
①v-show:不会对dom进行添加和删除,而是通过改变display属性的值,来完成显示和隐藏的。
②v-if:通过对dom进行添加和删除,来完成显示和隐藏的
2.使用:
①如果dom元素频繁地显示和隐藏,那么用v-show,这样效率高(因为dom元素的添加和删除会引起页面的重绘和重排)
②如果dom元素不会频繁地显示和隐藏,用v-if。
84、请你谈谈Cookie的弊端
a. 每个特定的域名下最多生成的cookie个数有限制
b. IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie
c. cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节
d. 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。
85、解释响应式布局,怎么实现的?优缺点?
响应式布局根据不同的浏览器分辨率和尺寸来展示页面结构,行为,表现的设计方式
原理:通过媒体查询检验不同的设备屏幕尺寸做处理,页面头部必须有meta声明viewport
优点:解决多设备适应问题,灵活性更强
缺点:工作量大,加载时间变长
86、什么是HTTPS,做什么用的呢?如何开启HTTPS?
(1)什么是HTTPS
https是http的加密版本,是在http请求的基础上,采用ssl进行加密传输。
(2)作用
加密数据,反劫持,SEO
(3)如何开启
生成私钥与证书,配置nginx,重启nginx
87、请问您对DOM事件流怎么理解?
事件流:就是事件的流向,即事件触发的顺序。
DOM事件流分为三个阶段:
1、第一个阶段是捕获阶段
2、第二个阶段是事件源
3、第三个阶段是冒泡阶段
88、jQuery是如何处理缓存的?
要处理缓存就是禁用缓存。
①、通过
.
p
o
s
t
(
)
方
法
来
获
取
数
据
,
它
的
默
认
就
是
禁
用
缓
存
的
。
②
、
通
过
.post()方法来获取数据,它的默认就是禁用缓存的。 ②、通过
.post()方法来获取数据,它的默认就是禁用缓存的。②、通过get()方法来获取数据,可以通过设置时间戳来获取避免缓存。
(在url后面jia+(+new Date))
③、通过
.
a
j
a
x
方
法
来
获
取
数
据
,
只
要
设
置
c
a
c
h
e
:
f
a
l
s
e
就
可
以
了
89
、
.ajax方法来获取数据,只要设置cache:false就可以了 89、
.ajax方法来获取数据,只要设置cache:false就可以了89、(this)和this关键字在jquery中有何不同?
(
t
h
i
s
)
他
是
返
回
一
个
j
Q
u
e
r
y
对
象
,
你
可
以
调
用
多
个
j
Q
u
e
r
y
方
法
t
h
i
s
代
表
当
前
这
个
元
素
,
他
是
J
a
v
a
S
c
r
i
p
t
关
键
词
中
的
一
个
,
表
示
上
下
文
中
的
当
前
d
o
m
元
素
。
你
不
能
对
他
调
用
j
Q
u
e
r
y
方
法
,
直
到
他
被
(this)他是返回一个jQuery对象,你可以调用多个jQuery方法 this 代表当前这个元素,他是JavaScript关键词中的一个,表示上下文中的当前dom元素。你不能对他调用jQuery方法,直到他被
(this)他是返回一个jQuery对象,你可以调用多个jQuery方法this代表当前这个元素,他是JavaScript关键词中的一个,表示上下文中的当前dom元素。你不能对他调用jQuery方法,直到他被()函数包裹
90、移动端是如何调试的?
真机调试之android手机+Chrome
真机调试之iphone +Safari
UC浏览器
模拟手机调试
微信内置浏览器调试
Debuggap(移动端调试工具)
抓包
为什么虚拟dom会提高性能?
虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能。具体实现步骤如下:
用JavaScript对象结构表示DOM树的结构;然后用这个树构建一个真正的DOM树,插到文档当中当状态变更的时候, 重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把2所记录的差 异应用到步骤1所构建的真正的DOM树上,视图就更新了。
92、页面导入样式时,使用link和@import有什么区别?
相同的地方,都是外部引用CSS方式,
区别:
- 范畴不同:link是xhtml标签,除了加载css外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS
- 加载顺序:link引用CSS时候,页面载入时同时会加载;@import需要在页面完全加载以后加载,而且@import被引用的CSS会等到引用它的CSS文件被加载完才加载
- 兼容问题:link是xhtml标签,无兼容问题;@import是在css2.1提出来的,低版本的浏览器不支持
- 是否支持js改变样式:link支持使用javascript控制去改变样式,而@import不支持
- 权重级别:link方式的样式的权重高于@import的权重
- 其他:import在html使用时候需要
95、简述for…in和for…of的区别
- 一般推荐在循环对象属性的时候,使用for…in;在遍历数组的时候,使用for…of;
- for…in循环出来的是key ,for…of循环出来的是value;
- for…of是ES6新引入的特征,修复了ES5引入的for…in 的不足;
- for…of不能循环普通的对象,需要通过和Object.keys()搭配使用,先获取对象的所有key的数组,然后遍历
96、HTML5中新的输入类型属性
①search:用于搜索域,比如站点搜索或 Google 搜索,域显示为常规的文本域。
②url :用于应该包含 URL 地址的输入域在提交表单时,会自动验证 url 域的值。
③email:用于应该包含 e-mail 地址的输入域,在提交表单时,会自动验证 email 域的值。
④datetime:选取时间、日、月、年(UTC 时间)
⑤date:选取日、月、年
⑥month:选取月、年
⑦week:选取周和年
⑧time:选取时间(小时和分钟)
⑨datetime-local:选取时间、日、月、年(本地时间)
⑩number:用于应该包含数值的输入域,您还能够设定对所接受的数字的限定。
①①range:用于应该包含一定范围内数字值的输入域,类型显示为滑动条。
97、HTML5有哪些的新特性?
HTML5中最有趣的新特性:
- 二维画图中的元素
- 媒体播放的视频 和音频元素
- 支持本地存储
- 新的内容特定元素,如
,
,
,
,
,
98、Canvas是什么?怎样写Canvas?
Canvas是HTML5的一个元素,它使用JavaScript在网页上绘制图形。Canvas是一个矩形区域。它的每一个像素都可以由HTML5语言来控制。使用Canvas绘制路径、框、圆、字符和添加图像有几种方法。
如果要在我们的HTML文档中添加Canvas标签,我们需要ID、宽度和高度。下面是如何将基本Canvas标签写入HTML文档的示例。
99、什么是vue的生命周期?它分为几个阶段?它的作用是什么?
Vue生命周期
Vue 实例从创建到销毁的过程,就是生命周期。
也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
阶段
它可以总共分为11个阶段:
创建前/后(1.beforeCreate,2.created),
载入前/后(3.beforeMount, 4.mounted),
更新前/后(5.beforeUpdate, 6.updated),
销毁前/后(7.beforeDestroy,8.destroyed),
激活时/未激活时(9.activated, 10.deactivated),
当捕获一个来自子孙组件的错误时被调用(11.errorCaptured)
作用:
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
100、HTML5中新的输入类型属性
1.search,url,email,datetime,date,month,week,time,datetime-local,number,range
2.h5新特性canvas,auio,vedio,本地存储,
101、h5新增的API 1.多媒体 2.地理定位:现实开发中,通过调用第三方API(如百度地图)来实现地理定位信息 3.全屏方法 Node.requestFullScreen() 开启全屏显示 Node.cancelFullScreen() 关闭全屏显示 document.fullScreen检测当前是否处于全屏 4.本地存储 5.历史管理 pushState(data, title, url) 追加一条历史记录。 replaceState(data, title, url) 与pushState()基本相同,不同之处在于replaceState(),只是替换当前url,不会增加/减少历史记录。 onpopstate事件,当前进或后退时则触发 6.离线应用 7.文件读取 8.网络状态
102、isicroll和Swiper
Swiper常用于移动端网站的内容触摸滑动
Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端,以及PC端网站。
Swiper能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。
Swiper开源、免费、稳定、使用简单、功能强大,是架构移动终端网站的重要选择!
isicroll主要是页面内的定位,定位光标,显示滚动条等
iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件。一般用来做 例如:上拉加载、下拉刷新
103、说一下自己是怎么写响应式布局的?rem是怎么计算的?
响应式布局主要是用的媒体查询@media,支持IE9以上及其它浏览器。
可以查询设备分辨率,浏览器宽度等,设置不同的样式或者直接引入不同的样式表。
rem是根据(根元素)html的font-size来设定的。
104、了解几种跨域的方法,jsonp跨域原理?
跨域的方法:jsonp,webSocket,postMessage,window,name+iframe,cors.jsonp
跨域原理:利用
- Modal :代表数据模型,数据和业务逻辑都在modal层中定义;
- View,:代表UI视图,负责数据的展示;
- ViewModall:负责监听modal中数据的改变并且控制视图的更新,处理用户交互操作;
Modal和View:并无直接关联,而是通过viewmodal来进行联系的,modal和viewmodal之间有着双向数据绑定的关系;
108、new操作符具体干了些什么?
1).创建一个空对象,并且this变量引用该对象,同时还继承了该函数的属性
2).属性和方法被加入到this引用的对象中
3).新创建的对象由this引用,并且最后隐式的返回this
109、attribute和property的区别是什么?
attribute是dom元素在文档中作为html标签拥有的属性
property是dom元素在js中作为对象拥有的属性
110、this、target和currentTarget的区别?
1)target:真正的事件流,不会随着事件的流动而流动
2)currentTarget:事件流到哪个元素currentTargent就是那个元素,即currentTargent会随着事件流的流动而流动。
3)this:也是事件源,跟currentTargent一样,但是,this有更广泛的意思。
111、为什么利用多个域名来提供网站资源会更有效?
1)突破浏览器的并发限制(浏览器同一域名最大的并发请求数量为6个,ie6为2个)
2)节约cookie带宽
3)CDN缓存更方便
4)防止不必要的安全问题(尤其是cookie的隔离尤为重要)
5)节约主机域名连接数,优化页面响应速度
112、输入url后的加载过程
1)查找域名对应IP地址
2)建立连接(TCP的三次握手)
3)构建网页
4)断开连接(TCP的四次挥手)
113、清除浮动的方法有哪些?
1)给父元素给一个高度,但是违背了高度自适应的原则
2)给父元素设置overflow:hidden;
3)在浮动的子元素末尾添加一个空div,并设置如下:
{clear:both;height:0;overflow:hidden},
后两个属性是为了解决IE6不能识别较小高度的容器问题
4)父元素:after{content:“”;display:block;clear:both;height:0;overflow:hidden;visibility:hidden;}
114、如何添加HTML元素的事件,有几种方法?
1)在标签中直接添加,例如:
2)dom.οnclick=function(){}
3)事件监听:
主流浏览器:addEventListener(“onclick”,function(){},false/true),
事件流动方式:false-》事件冒泡,true-》事件捕获
IE:attachEvent(“onclick”,function(){})
115、写一段代码,截取字符串abcdefg的efg
方法1:只考虑当前字符串
let str=“abcdefg”;
console.log(str.splice(str.length-3));//因为最大下标是str.length-1;
console.log(str.substring(str.length-3));//因为最大下标是str.length-1;
console.log(str.substr(str.length-3));//因为最大下标是str.length-1;不推荐使用该方法,因为ECMAScript没有对它标准化
方法2:写一个方法
function cut(str){
//判断是否满足长度大于等于3
if(str.length<3){
alert(“字符串不符合截取规则”);
return;
}
let newStr="";
newStr=str.substring(str.length-3);
return newStr;
}
116、Vue的优缺点是什么
优点:低耦合,可重用性,独立开发,可测试,渐进式
缺点:不利于SEO,社区维护力度不强,相比还不够成熟
117、雪碧图
优点:
减少对服务器的请求次数,比如页面有五个图标,把他们放到一张背景图上,只需要加载一次。然后用css定位从这张图片来取就可以了;
因为浏览器同一时间能够加载的资源数是一定的,IE 8是6个,Chrome是6个,Firefox是8个,减少了页面的请求次数,自然会提高了页面的加载速度
缺点:
维护麻烦,如果修改其中的一张图,你需要修改整张图
高清失真,为了适应不同的分辨率,可能要准备多个规格的图片
118、HTTP状态码共分为5种类型:
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
119、ES6里面你用过什么?
1)块级作用域 -let
2)衡量 -const
3)解构函数
4)解构对象
5)模板字符串
6)解构参数
7)展开操作符
8)剩余操作符
9)箭头函数
10)对象表达式
11)对象属性名
12)对比两个值是否相等
13)把一个对象的值复制到另一个对象里
14)设置对像的prototype
15)proto
16)Supper(www.cnblogs.com/jinly/p/106…
17)迭代器
18)class类
19)静态方法
20)继承
21)模块化
22)Get set
120、diff算法
1)把树形结构按照层级分解,只比较同级元素。
2)给列表结构的每个单元添加唯一的key属性,方便比较。
3)React只会匹配相同class的component(这里的class指的是组件的名字)。
4)合并操作,调用component的setState方法的时候,React将其标记为dirty。
到每一个事件循环结束,React检查所有标记dirty的component重新绘制。
选择性子树渲染。开发人员可以重写shouldComponentUpdate提高diff的性能。
121、项目上线的流程是怎样的?
1.流程建议
(1)模拟线上的开发环境
(2)模拟线上的测试环境
(3)可连调的测试环境
(4)自动化的上线系统
(5)合前后端的开发流程
122、git常用命令
专用名词的译名: Workspace:工作区 Index/Stage: 暂存区
Repository:仓库区(或本地仓库) Remote:远程仓库
git init 在当前目录新建一个Git代码库
git add 添加
git commit 提交
git clone 克隆
git branch 列出所有本地分支
git push [remote] [branch] 上传本地指定分支到远程仓库
git checkout 切换到指定分支,并更新工作区
git merge [branch] 合并指定分支到当前分支
git status 显示有变更的文件
git log 显示当前分支的版本历史
123、懒加载的实现原理?
意义:
懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
实现原理:
先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用。
实现方法:
1.纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟。
2.条件加载,符合某些条件,或触发了某些事件才开始异步下载。
3.可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到图片前一定距离便开始加载,这样能保证用户拉下时正好能看到图片。
124、对Node.js的理解
1.Node.js 概念
Node.js是基于V8引擎的javascript运行环境
Node.js引用了事件驱动,非阻塞式I/O模型
Node.js轻量又高效能在本地运行javascript
2.Node.js能干什么
提供数据给浏览器使用
数据分析 数据统计
保存用户发送过来的数据
3.Node.js的五大模块
http 开启一个web服务 给浏览器使用
url 给浏览器发送请求用 还能传递参数 get
fs 服务器端读取文件(找文件)
qureystring 处理浏览器发送过来的数据 get post
path 处理文件路径
125、目前最为主流浏览器以及内核:
1、IE—————————Trident内核
2、Firefox——————Gecko内核
3、GoogleChrome——————以前是Webkit现在是Blink内核
4、Safari(苹果公司开发的浏览器)————Webkit内核
5、Opera————最初Presto内核,后来是Webkit现在是Blink
126、如何解决HTML在各种浏览器的兼容性问题
*{
margin:0;
padding:0;
}
127、vue双向绑定是什么?
vue双向绑定是通过数据劫持结合发布者、订阅者模式的方式来实现的,通过object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
128、jQ源码中值得借鉴的?
(1)使用模块化思想,模块化保持独立,不会导致多个开发人员合作时产生冲突
(2)在设计程序时,要结构清晰,高内聚,低耦合
(3)利用多态的方式,实现方法的重载,提高代码的复用率
(4)jQuery的链式调用以及回溯
(5)jQuery.fn.extend与jQuery.extend方法来实现扩展静态方法或实例方法
129、如何优化页面,加快页面的加载速度
1.优化图片资源的格式和大小
2.开启网络压缩
3.使用浏览器缓存
4.减少重定向请求
5.使用CDN存储静态资源
6.减少DNS查询次数
7.压缩css和js内容
130、delete和Vue.delete删除数组的区别
delete:
只是被删除的元素变成了 empty/undefined,其他的元素的键值还是不变。
只是删除数组的值,但是它依然会在内存中占位置
Vue.delete:
直接删除了数组 改变了数组的键值。
会删除数组在内存中的占位
- splice:直接删除了数组,改变了数组的键值,删除在数组中的占位
131、怎么定义vue-router的动态路由,怎么获取传过来的参数
设置:在router目录下的index.js文件中,对path属性加上/:id
获取:使用router对象的params.id
132、哪些css属性可以继承?
可继承:font-size font-family color ul li dl dt dd
不可继承:border margin padding width height
133、iconfont的利与弊
1、iconfont的利
① iconfont图像放大后,不会失真。(与文字一样放大后不会失真)
② iconfont节省流量
③ iconfont在颜色变幻方面很简单(跟变换字体颜色一样直接使用color)
2、iconfont的弊
① iconfont不能支持一个图像里面混入多重颜色
② iconfont的使用没有使用图片那么直接,简单。
134、iconfont怎么做?
阿里巴巴的iconfont
如果我们手里有一些图标,想转换为iconfont的话,可以直接使在线工具转换:image.online-convert.com/convert-to-…
135、一个大数组,可能存了100万个数字,从中取出来第二大的数的下标,有什么快速方法?
136、什么是逻辑短路?
逻辑短路是对于逻辑运算而言,是指仅计算逻辑表达式中的一部分便能确定结果,而不对整个表达式进行计算的现象。
137、的作用是什么?
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
eg:
比如有一个列表和一个详情,那么用户就会经常执行打开详情=>返回列表=>打开详情…这样的话列表和详情都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染
138、style标签写在body后与body前有什么区别?
页面加载自上而下 当然是先加载样式。
写在body标签后由于浏览器以逐行方式对HTML文档进行解析,
当解析到写在尾部的样式表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染,在windows的IE下可能会出现FOUC现象(即样式失效导致的页面闪烁问题)
139、iframe的优缺点?
优点:
a. 解决加载缓慢的第三方内容如图标和广告等的加载问题
b. iframe无刷新文件上传(blog.csdn.net/lee\_sire/a…
c. iframe跨域通信
缺点:
a. iframe会阻塞主页面的Onload事件
b. 无法被一些搜索引擎索引到
c. 页面会增加服务器的http请求
d. 会产生很多页面,不容易管理。
140、call和apply的区别
call和apply的作用是一样的,区别在于传入参数的不同
两者的区别:
apply()方法有两个参数,分别是运行函数的作用域,另一个是参数数组(可以是Array也可以是arguments)。
Call()方法的第一个参数和apply()的第一个参数一样,其它参数就是调用函数的参数(相当于把,apply第二个参数的每个元素单列出来)
(解释call和apply是干什么的)
每个函数都有两个非继承而来的方法apply()和call(),这两个方法的用途都是用来调用函数(在特定的作用域中),实际上等于设置函数体内的this对象的值。调用函数,实际上就是调用该函数对象的call内部方法。
141、Vue的双向数据绑定原理是什么?
v-model实际就是v-bind,v-on
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
142、谈谈你对生命周期的理解
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后:
在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。
在created阶段,vue实例的数据对象data有了,el还没有。
载入前/后:
在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:
当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:
在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
143、什么是vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
144、第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子。
145、DOM渲染在哪个周期中就已完成?
DOM 渲染在 mounted 中就已经完成了。
146、vuex有哪几种属性?
5种,分别是state、getter、mutation、action、module
1、state(保存数据 )
2、getter类似vue的计算属性(从基本数据派生的数据 )
3、mutation (修改state中的数据与跟踪状态有关)store.commit(提交更改数据的方法,同步!
4、action 可以提交mutation 在action中可以执行store.commit,并且action中可以有异步操作,如果要使用action,则需要执行store.dispatch
5、Module 就是模块化Vuex
147、说说你对SPA单页面的理解,它的优缺点分别是什么?
SPA(single page application)单页面应用,即一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转,而是由路由机制实现HTML内容的变换
优点:
用户体验好,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染,所以SPA相对对服务器的压力小
前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理
缺点:
初次加载耗时多
不利于SEO优化
不支持低版本的浏览器,最低只支持到IE9
不可以使用浏览器的导航按钮,需要自行配置路由实现前进、后退。
148、怎样理解单向数据流
这个概念出现在组件通信。父组件是通过 prop 把数据传递到子组件的,但是这个 prop 只能由父组件修改,子组件不能修改,否则会报错。
子组件想修改时,只能通过
e
m
i
t
派
发
一
个
自
定
义
事
件
,
父
组
件
接
收
到
后
,
由
父
组
件
修
改
。
也
可
以
基
于
此
方
法
实
现
兄
弟
组
件
(
父
子
组
件
、
隔
代
组
件
)
之
间
的
信
息
通
信
。
149
、
v
u
e
常
用
的
事
件
修
饰
符
?
1
、
.
p
r
e
v
e
n
t
:
阻
止
默
认
行
为
;
2
、
.
s
t
o
p
:
阻
止
单
击
事
件
冒
泡
;
3
、
.
s
e
l
f
:
当
事
件
发
生
在
该
元
素
本
身
时
候
会
触
发
;
4
、
.
c
a
p
t
u
r
e
:
事
件
侦
听
,
事
件
发
生
的
时
候
会
调
用
(
使
用
捕
获
,
冒
泡
的
时
候
是
不
理
的
)
5
、
.
o
n
c
e
事
件
只
会
触
发
一
次
150
、
自
定
义
指
令
(
v
−
c
h
e
c
k
、
v
−
f
o
c
u
s
)
的
方
法
有
哪
些
?
它
有
哪
些
钩
子
函
数
?
还
有
哪
些
钩
子
函
数
参
数
?
(
1
)
1
、
全
局
定
义
指
令
:
在
v
u
e
对
象
的
d
i
r
e
c
t
i
v
e
方
法
里
面
有
两
个
参
数
,
一
个
是
指
令
名
称
,
另
外
一
个
是
函
数
v
u
e
.
d
i
r
e
c
t
i
v
e
2
、
组
件
内
定
义
指
令
:
d
i
r
e
c
t
i
v
e
s
(
2
)
钩
子
函
数
:
b
i
n
d
(
绑
定
事
件
触
发
)
、
i
n
s
e
r
t
e
d
(
节
点
插
入
的
时
候
触
发
)
、
u
p
d
a
t
e
(
组
件
内
相
关
更
新
)
c
o
m
p
o
n
e
n
t
U
p
d
a
t
e
d
:
指
令
所
在
组
件
的
节
点
全
部
更
新
后
调
用
。
u
n
b
i
n
d
:
只
调
用
一
次
,
指
令
与
元
素
解
绑
时
调
用
。
(
3
)
钩
子
函
数
参
数
:
e
l
、
b
i
n
d
i
n
g
、
v
n
o
d
e
:
虚
拟
节
点
。
o
l
d
V
n
o
d
e
:
上
一
个
虚
拟
节
点
。
151
、
构
建
的
v
u
e
−
c
l
i
工
程
都
用
了
哪
些
技
术
,
它
们
的
作
用
分
别
是
什
么
?
1
、
v
u
e
.
j
s
:
v
u
e
−
c
l
i
工
程
的
核
心
,
主
要
特
点
是
双
向
数
据
绑
定
和
组
件
化
系
统
。
2
、
v
u
e
−
r
o
u
t
e
r
:
v
u
e
官
方
推
荐
使
用
的
路
由
框
架
。
3
、
v
u
e
x
:
专
为
V
u
e
.
j
s
应
用
项
目
开
发
的
状
态
管
理
器
,
主
要
用
于
维
护
v
u
e
组
件
间
共
用
的
一
些
变
量
和
方
法
。
4
、
a
x
i
o
s
(
或
者
f
e
t
c
h
、
a
j
a
x
)
:
用
于
发
起
G
E
T
、
或
P
O
S
T
等
h
t
t
p
请
求
,
基
于
P
r
o
m
i
s
e
设
计
。
∗
∗
∗
f
e
t
c
h
是
原
生
j
s
写
的
,
t
h
e
n
两
次
,
t
h
e
n
回
来
的
是
r
e
s
p
o
n
s
e
(
响
应
对
象
)
对
象
,
赋
给
r
e
s
o
l
v
e
a
x
i
o
s
是
封
装
好
的
,
t
h
e
n
一
次
5
、
v
u
x
等
:
一
个
专
为
v
u
e
设
计
的
移
动
端
U
I
组
件
库
。
6
、
创
建
一
个
e
m
i
t
.
j
s
文
件
,
用
于
v
u
e
事
件
机
制
的
管
理
。
7
、
w
e
b
p
a
c
k
:
模
块
加
载
和
v
u
e
−
c
l
i
工
程
打
包
器
。
152
、
路
由
跳
转
编
程
式
导
航
:
t
h
i
s
.
emit 派发一个自定义事件,父组件接收到后,由父组件修改。也可以基于此方法实现兄弟组件(父子组件、隔代组件)之间的信息通信。 149、vue常用的事件修饰符? 1、.prevent: 阻止默认行为; 2、.stop: 阻止单击事件冒泡; 3、.self: 当事件发生在该元素本身时候会触发; 4、.capture: 事件侦听,事件发生的时候会调用(使用捕获,冒泡的时候是不理的) 5、.once 事件只会触发一次 150、自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数? (1) 1、全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数vue.directive 2、组件内定义指令:directives (2) 钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新) componentUpdated:指令所在组件的节点全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。 (3) 钩子函数参数:el、binding、vnode:虚拟节点。oldVnode:上一个虚拟节点。 151、构建的 vue-cli 工程都用了哪些技术,它们的作用分别是什么? 1、vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件化系统。 2、vue-router:vue官方推荐使用的路由框架。 3、vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。 4、axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。 *** fetch是原生js写的,then两次,then回来的是response(响应对象)对象,赋给resolve axios是封装好的,then一次 5、vux等:一个专为vue设计的移动端UI组件库。 6、创建一个emit.js文件,用于vue事件机制的管理。 7、webpack:模块加载和vue-cli工程打包器。 152、路由跳转 编程式导航:this.
emit派发一个自定义事件,父组件接收到后,由父组件修改。也可以基于此方法实现兄弟组件(父子组件、隔代组件)之间的信息通信。149、vue常用的事件修饰符?1、.prevent:阻止默认行为;2、.stop:阻止单击事件冒泡;3、.self:当事件发生在该元素本身时候会触发;4、.capture:事件侦听,事件发生的时候会调用(使用捕获,冒泡的时候是不理的)5、.once事件只会触发一次150、自定义指令(v−check、v−focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?(1)1、全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数vue.directive2、组件内定义指令:directives(2)钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)componentUpdated:指令所在组件的节点全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。(3)钩子函数参数:el、binding、vnode:虚拟节点。oldVnode:上一个虚拟节点。151、构建的vue−cli工程都用了哪些技术,它们的作用分别是什么?1、vue.js:vue−cli工程的核心,主要特点是双向数据绑定和组件化系统。2、vue−router:vue官方推荐使用的路由框架。3、vuex:专为Vue.js应用项目开发的状态管理器,主要用于维护vue组件间共用的一些变量和方法。4、axios(或者fetch、ajax):用于发起GET、或POST等http请求,基于Promise设计。∗∗∗fetch是原生js写的,then两次,then回来的是response(响应对象)对象,赋给resolveaxios是封装好的,then一次5、vux等:一个专为vue设计的移动端UI组件库。6、创建一个emit.js文件,用于vue事件机制的管理。7、webpack:模块加载和vue−cli工程打包器。152、路由跳转编程式导航:this.router.push()
声明式跳转:< router-link to=””>
153、谈一谈Vue组件之间的参数传递?
父组件传给子组件:子组件通过props方法接收数据;
子组件传给父组件:$emit方法传递参数;
兄弟间组件通信:利用Vuex实现。
154、什么是MVVM?
(1) MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象(桥梁)。在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互, Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
(2) ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
155、mvvm和mvc区别?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller 演变成mvvm中的viewModel。
mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
156、的作用是什么?
包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。
157、v-show和v-if指令的共同点和不同点
v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
如何通过HR⾯
HR通常是程序员⾯试的最后⼀⾯,讲道理刷⼈的⼏率不⼤,但是依然有⼈倒在了这最后⼀关上,我们会从HR的⻆度出发来分析如何应对HR⾯.
HR⾯的⽬的
HR⾯往往是把控⼈才质量的最后⼀关,与前⾯的技术⾯不同,HR⾯往往侧重员⼯⻛险的评估与基本的员⼯素质.
录⽤⻛险评估,这部分是评估候选⼈是否具备稳定性,是否会带来额外的管理⻛险,是否能⻢上胜任⼯作,⽐如频繁的跳槽会带了稳定性的⻛险,HR会慎重考虑这⼀点,⽐如在⾯试中候选⼈体现出了「杠精」潜质,HR会担⼼候选⼈在⼯作中会难以 与他⼈协作或者不服从管理,带来管理⻛险,再⽐如,虽然国家明确规定在招聘中不得有性别、年龄等歧视,但是⼀个⼤龄 已婚妇⼥会有近期产⼦的可能性,可能会有⻓期的产假,HR也会做出评估。
员⼯素质评估,这部分评估候选⼈是否具备职场的基本素质,是否有基本的沟通能⼒,是否有团队精神和合作意识等等,⽐如
⼀个表现极为内向的候选⼈,HR可能会对其沟通能⼒产⽣怀疑.
所以在与HR交流中要尽量保持踏实稳重、积极乐观的态度,切忌暴露出夸夸其谈、负能量、浮躁等性格缺陷。
HR⾯的常⻅问题
你对未来3-5年的职业规划
⽬的: 这个问题就是考察候选⼈对未来的规划能⼒,主要想通过候选⼈的规划来嗅出候选⼈对⼯作的态度、稳定性和对技术的追求.
分析: ⼀定要在你的回到中体现对技术的追求、对团队的贡献、对⼯作的态度,不要谈⼀些假⼤空的东⻄,或者薪资、职位这些太过于功利的东⻄,⽽且最好体现出你的稳定性,如果是校招⽣或者⼯作没⼏年的新⼈最好不要涉及创业这种话题,⼀⽅⾯职场新⼈计划没⼏年就创业,这种很不切实际,说明候选⼈没法按实际出发,另⼀⽅⾯说明候选⼈的稳定性不够.
还真有候选⼈因为谈创业被HR刷的建议分三部分谈:
- ⾸先表示考虑过这个问题(有规划),如何谈⼀谈⾃⼰的现状(结合实际).
- 接着从⼯作本身出发,谈谈⾃⼰会如何出⾊完成本职⼯作,如何对团队贡献、如何帮助带领团队其他成员创造更多的价值、如何帮助团队扩⼤影响⼒.
- 最后从学习出发,谈谈⾃⼰会如何精进领域知识、如何通过提升⾃⼰专业能⼒,如何反哺团队.
⾄于想成为技术leader还是技术专家,就看⾃⼰的喜好了.
如何看待加班(996)?
⽬的: 考察候选⼈的抗压能⼒和责任⼼
分析: 这个问题⼏乎是必问的,虽然996ICU事件闹得沸沸扬扬,但是官⽅的态度很暧昧,只⼝头批评从没有实际⾏动,基本上是默许企业违反劳动法的,除了个别外企在国内基本没可能找到不加班的公司,所以在这个⾯试题中尽量体现出⾃⼰愿意 牺牲⾃我时间来帮助团队和企业的意愿就⾏了,⽽且要强调⾃⼰的责任⼼,如果真的是碰到⽆意义加班,好好学习怎么⽤vscode刷LeetCode划⽔是正道.
建议:
- 把加班分为紧急加班和⻓期加班
- 对于紧急加班,表示这是每个公司都会遇到的情况,⾃⼰愿意牺牲时间帮助公司和团队
- 对于⻓期加班,如果是⾃⼰⻓期加班那么会磨练⾃⼰的技能,提⾼⾃⼰的效率,如果是团队⻓期加班,⾃⼰会帮助团队找到问题,利⽤⾃动化⼯具或者更⾼效的协作流程来提⾼整个团队的效率,帮助⼤家摆脱加班
当然了,就算你提⾼了团队效率,还是会被安排更多的任务,加班很多时候仅仅是⽬的,但是你不能说出来啊,尤其是⼀些候 选⼈很强硬得表示⻓期加班不接受,其实可以回答的更委婉,除⾮你是真的对这个公司没兴趣,如果以进⼊这个公司为第⼀
⽬的,还是做个⾼姿态⽐较好.
⾯对⼤量超过⾃⼰承受能⼒且时间有限的⼯作时你会怎么办?
⽬的: 考察候选⼈时间管理和处理⼤量任务的能⼒,当然也会涉及⼀定的沟通能⼒
分析: 程序员的⼯作内容可能⼤部分时间并不在写代码上,⽽是要处理各种会议、需求和沟通,通常都属于⼯作超负荷的状态,⾯对上⾯这种问题不建议以加班的⽅式来解决,因为主要考察的是你的时间管理能⼒和沟通能⼒,这些要素要在回答中 体现出来
建议:
- 将⼤量任务分解为紧急且重要、重要但不紧急、紧急但不重要、不重要且不紧急,依次完成上述任务,在这⾥体现出时间管理的能⼒
- 与⾃⼰的领导沟通将不重要的任务放缓执⾏或者砍掉,或者派给组内的新⼈处理,在这⾥体现出沟通能⼒
你之前在上海为什么现在来北京发展?
⽬的: 考察候选⼈的稳定性和职业选择
分析: 这个问题⼀般是上份⼯作在异地的情况下⼤概率出现,HR主要担⼼候选⼈异地换⼯作可能会不稳定,有短期内离职
⻛险,这个时候不建议说"北京互联⽹公司多,机会多"这种话(合着觉得北京好跳槽?),回答最好要体现出⾃⼰的稳定性,⽐ 如"⼥朋友在北京,⻓期异地,准备来北京⼀起发展" “家在北京,回北京发展” 等等,潜台词就是以后会在北京发展,不会在多地之间来回摇摆.
为什么从上⼀家公司离职?
⽬的: 考察离职原因,候选⼈离职⻛险评估
分析: 这个问题经常会在跳槽的时候问到,这个时候切忌吐槽上⼀家公司或者⾃⼰的上⼀任⽼板,尽量从职业发展的⻆度来回答,凸显⾃⼰的稳定性和渴望学习上升的决⼼,⾄于⼀些敏感话题,⽐如加班太多、薪资太低这种问题也是可以谈的, 毕竟你跳槽的诉求就是解决上家公司碰到的问题,但是不能触碰刚才提到的底线问题,切忌吐槽向.
建议:
- 因为⼯资低、离家远、加班多、技术含量低等等原因离职
- 因为离家远花费在路途上的时间过多,不如⽤来充电,因为加班多导致没有时间充电,⽆法提⾼等等
除了不要有负能量和吐槽向,这个部分可以坦诚得说出来
你还有其他公司的Offer吗?
⽬的: 评估候选⼈是否有短时间内⼊职其他公司的可能性
分析: 很多时候并不是候选⼈完美符合⼀个岗位的要求,HR当然想要⼀个技术更好、要钱更少、技术更匹配的候选⼈, 但是候选⼈⼀般都会有这样或者那样的⼩问题。
⽐如,你的表现是可以胜任⽬前的岗位的,但是这个岗位不是很紧急,HR可能把你当做备胎,来找⼀个性价⽐更⾼的候选⼈.
⽐如,你的表现很好,履历优秀,HR不知道能不能100%拿下你.
所以如果你很希望加⼊这个公司,最好要做到「欲擒故纵」,既要体现⾃身的市场竞争⼒,⼜要给到HR⼀定的压⼒.
所以,即使你已经拿了全北京城互联⽹公司的offer了,也不要说⾃⼰offer多如⽜⽑,⼀副满不在乎的样⼦,这样会给HR造成他⼊职可能性不⼤的错觉,因为他的选择太多了.
当然,也不要跪在地上舔:“加⼊公司是我的梦想,我只等这⼀个offer”,放⼼吧,⼀定被hr放到备胎⼈才库中. 建议:
- 表明⾃⼰有三四个已经确认过的offer了(没有offer也要吹,但是不要透露具体公司)
- 但是第⼀意向还是本公司,如果薪资差距不⼤,会优先考虑本公司
- 再透露出,有⼀两个offer催得⽐较急,希望这边快点出结果
如何与HR谈薪资?
HR与你谈论薪资经常有如下套路:
HR: 您期望的薪资是多少? 你: 25K。
OK,你已经被HR成功套路。这个时候你的最⾼价就是25K了,然后HR会顺着这个价往下砍,所以你最终的薪资⼀般都会低于25K。等你接到offer,你的⼼⾥肯定充满了各种“悔恨”:其实当时报价26、27甚⾄28、29也是可以的。
正确的回答可以这样,并且还能够反套路⼀下HR:
HR: 您期望的薪资是多少?
你: 就我的⾯试表现,贵公司最⾼可以给多少薪⽔?
哈哈,如果经验不够⽼道的HR可能就真会说出⼀个报价(如25K)来,然后,你就可以很开⼼地顺着这个价慢慢地往上谈了。所以这种情况下,你最终的薪资肯定是⼤于25K的。当然,经验⽼道的HR会给你⼀句很官⽅的套话:
HR: 您期望的薪资是多少?
你: 就我的⾯试表现,贵公司最⾼可以给多少薪⽔?
HR: 这个暂且没法确定,要结合您⼏轮⾯试结果和⽤⼈部⻔的意⻅来综合评定。
如果HR这么回答你,我的建议是这样的:
虽然薪资很重要,但是我个⼈觉得这不是最重要的。我有以下建议:
如果你觉得你技术⾯试效果很好,可以报⼀个⾼⼀点的薪资,这样如果HR想要你,会找你商量的。如果你觉得技术⾯试效果⼀般,但是你⽐较想进这家公司,可以报⼀个折中的薪资。
如果你觉得⾯试效果很好,但是你不想进这家公司,你可以适当“漫天要价”⼀下。 如果你觉得⾯试效果不好,但是你想进这家公司,你可以开⼀个稍微低⼀点的⼯资。
需要注意的是,⾯试求职是⼀个双向选择的过程。⾯试应该做到不卑不亢,千万不要因为⾯试结果不好,就低声下⽓地乞求⼯作,每个⼈的⼯作经历和经验都是不⼀样的,技术⾯试不好,知道⾃⼰的短板针对性地补缺补差就⾏,⽽不是在
⼈事关系上动歪脑筋。
参考:
⾯试技巧 | 技术岗位⾯试如何与HR谈薪
⾯试回答问题的技巧
技术⾯试通常⾄少三轮:
- 基础⾯试: 主要考察对岗位和简历中涉及到基础知识部分的提问,包括⼀部分算法和场景设计的⾯试题,这⼀⾯可能会涉及现场coding.
- 项⽬⾯试: 主要考察简历中涉及的项⽬,会涉及你项⽬的相关业务知识、扮演⻆⾊、技术取舍、技术攻坚等等.
- HR⾯试: 这⼀⾯通常是HR把关,主要涉及⾏为⾯试,考察候选⼈是否价值观符合公司要求、⼯作稳定性如何、沟通协作能⼒如何等等.
当然,对于初级岗或者校招⽣会涉及⼀轮笔试,相当多的公司会在现场⾯之前进⾏⼀轮电话⾯试,⽬的是最快速有效地把不符合要求的候选⼈筛除,对于个别需要跨部⻔协作的岗位会涉及交叉⾯试,⽐如前端候选⼈会被后端的⾯试官⾯试,⼀些有管理需求的岗位或者重要岗位可能会涉及总监⾯试或者vp⾯.
⽽⼀个正常的技术⾯试流程(以项⽬⾯为例)分为⼤致三个部分: - ⾃我介绍
- 项⽬(技术)考察
- 向⾯试官提问
那么该如何准备技术⾯试,如何在⾯试中掌握主动权呢?
⾃我介绍
⼏乎所有的⾯试都是从⾃我介绍这个环节开始的,所以我们得搞清楚为什么⾃我介绍通常作为⼀个⾯试的开头.
为什么需要⾃我介绍
⾸先,有⼀个很普遍的问题就是⾯试官很可能才刚拿到你的简历,他需要在你⾃我介绍的时候快速浏览你的简历,因为技术
⾯试的⾯试官很多是⼀线的员⼯,⾯试候选⼈只是其⼯作中的⼀⼩部分,很多情况下是没有提前看过你的简历的.
其次,⾃我介绍其实是⼀个热身,⾯试官和候选⼈其实是陌⽣⼈,⾃我介绍不管是⾯试还是其他情况下,都是两个陌⽣⼈彼此交流的起点,也是缓解候选⼈与⾯试官之间尴尬的⼀种热身⽅式.
最后,⾃我介绍是展示⾃我、引出接下来技术⾯试的引⼦,是你⾃⼰指定技术⾯试⽅向的⼀次机会。知道了以上原因,我们才能进⾏准备更好的⾃我介绍。
⾃我介绍的⼏个必备要素
⾃我介绍归根到底是⼀个热身运动,因此切忌占⽤⼤量的篇幅,上来就把⾃⼰从出⽣的经历到⼤学像流⽔账⼀样吐出来的, 往往会被没耐⼼的⾯试官打断,⽽这也暴露了候选⼈讲话缺乏重点、沟通能⼒⼀般的缺点。
但是,⼀些关键信息是必须体现的,就我个⼈⽽⾔,以下信息是必备的:
个⼈信息: ⾄少要体现出⾃⼰的姓名、岗位和⼯作年限,应届⽣则必须要介绍⾃⼰的教育背景,如果⾃⼰的前东家是个⼤⼚(⽐如BAT)最好提及,⾃⼰的学历是亮点(985或者硕博或者类似于北邮这种CS强校)最好提及,其他的什么有没有⼥朋友、是不是独⽣⼦没⼈在意,不要占⽤篇幅。这个部分重点在于「你是谁?」。
技术能⼒: 简要地介绍⾃⼰的技术栈,切忌把⾃⼰只是简单使⽤过,写过⼏个Demo或者看了看⽂档的所谓「技术栈」也说出来,⼀旦后⾯问到算是⾃找尴尬。这个部分的重点在于「你会什么?」。
技能擅⻓: 重点介绍⾃⼰擅⻓的技术,⽐如性能优化、⾼并发、系统架构设计或者是沟通协调能⼒等等,切忌夸⼤其词,要实事求是,这是之后考察的重点。这个部分重点⾃在于「你擅⻓什么?」。
⾃我介绍要有⽬的性
要重点匹配当前岗位的技术栈
你的⾯试简历可能包含了各种各样的技术栈,但是在⾃我介绍过程中需要匹配当前岗位的技术要求.
就⽐如你⽬前⾯试的是移动端H5前端的开发岗位,就重点在⾃我介绍中突出⾃⼰在移动前端的经验,⽽此时⼤篇幅得讲述
⾃⼰如何⽤Node⽀撑公司的web项⽬就显得很不明智.
要在⾃我介绍中做刻意引导
如果你的⾃我介绍跟流⽔账⼀样,没有任何重点,其实⾯试官也很难办,因为他都没法往下接话…
⽽只要你稍作引导,绝⼤部分⾯试官就会接你的话茬,⽐如「你在⾃我介绍中重点提及了⼀个项⽬,碰到了⼀些难点,然后被你攻克了,效果如何如何好等等」,如果我是⾯试官⼀定会问「你的xx项⽬的xx难点后来是怎么解决的?」。
⾯试官的⽬的是考察候选⼈的能⼒,对候选⼈做出评估,因此需要知道候选⼈擅⻓什么,是否匹配岗位,⾯试官绝⼤多数情况下很乐意你这种有意⽆意的引导,这样双⽅的沟通和评估会很顺利,⽽不是故意刁难候选⼈。
如何准备⾃我介绍
其实最好的⽅法也是最笨的⽅法就是把⾃我介绍写下来,这个⾃我介绍⼀定要体现上⾯提到的⼏⼤必备要素,在⾯试前简单过⼏遍,能把⾃我介绍的内容顺利得表达出来即可,切忌跟背课⽂⼀样.
⾃我介绍的时间最好控制在1-3分钟之间,这些时间⾜够⾯试官把你的简历过⼀遍了,⾯试官看完简历后正好接着你的⾃我介绍进⾏提问是最舒服的节奏,别上来开始10分钟的演讲,⾯试官等待的时候会很尴尬,这么⻓的篇幅说明你的⾃我介绍⼀定是流⽔账式的.
技术考察
⼀个好的技术考察的开始,必须得有⾃我介绍部分好的铺垫和引导,有⼀种情况我们经常遇⻅:
候选⼈说了⼀⼤堆⾮重点的⾃我介绍,⾯试官⼀时语塞,完全get不到候选⼈的重点,也不知道候选⼈擅⻓什么、有什么亮点项⽬,然后就在他简历的技术栈中选了本公司也在⽤的技术,候选⼈这个时候也开始冒汗,因为这个技术 栈并不是他的擅⻓,回答的也磕磕绊绊,⾯试官的引导和深⼊追问也没有达到很好的效果,⾯试就在这种尴尬的
⽓氛中展开了,⾯试结束后⾯试官对候选⼈的评价是技术不熟练、没有深⼊理解原理,候选⼈的感受是,⾯试官专挑⾃⼰不会的问。
所以在前⾯的部分,⼀定要做好引导,把⾯试官的问题引到我们擅⻓的领域,但是这样还不够,正所谓不打⽆准备之仗,我们依然需要针对可能出现的问题进⾏准备.
那么如何准备可能的⾯试题?
⽐如你擅⻓前端的性能优化,在⾃我介绍的部分已经做好了引导,接下来⾯试官⼀定会重点考察你性能优化的能⼒,很可能会涉及很有深度的问题,即使你擅⻓这⽅⾯的技术,但是如果没有准备也可能临场乱了阵脚.
多重提问
⾃我多重提问的意思是,当⼀个技术问题抛出的时候,你可能⾯对更深层次的追问
依旧以前端性能优化为例,⾯试官可能的提问:
- 你把这个⼿机端的⽩屏时间减少了150%以上,是从哪些⽅⾯⼊⼿优化的?这个问题即使你没做过前端性能优化也能回答个七七⼋⼋,⽆⾮是组件分割、缓存、tree shaking等等,这是第⼀重⽐较浅的问题。
- 我看你⽤webpack中SplitChunksPlugin这个插件进⾏分chunk的,你分chunk的取舍是什么?哪些库分在同⼀个chunk, 哪些应该分开你是如何考虑的?如果你提到了SplitChunksPlugin插件可能会有类似的追问,如果没有实际操作过的候 选⼈这个时候就难以招架了,这个过程⼀定是需要⼀定的试错和取舍的.
- 在分chunk的过程中有没有遇到什么坑?怎么解决的?其实SplitChunksPlugin这个插件有⼀个暗坑,那就是chunk的id
⾃增性导致id不固定唯⼀,很可能⼀个新依赖就导致id全部打乱,使得http缓存失效.
以上只是针对SplitChunksPlugin插件相关的优化提问,当然也可能从你的性能测试⻆度、代码层⾯进⾏考察,但是思路是类似的。
因此不能把⾃⼰准备的问题答案停留在⼀个很浅显的层⾯,⼀⽅⾯⽆法展示⾃⼰的技术深度,另⼀⽅⾯在⾯试官的深度体情况下容易丢分,因此在⾃⼰的答案后⾯多进⾏⾃我的追问,看⼀看能不能把问题做的更深⼊。
答题法则
很多⾯试相关的宝典都推荐使⽤STAR法则进⾏问题的应答,我们不想引⼊这个额外的概念,基础技术⾯试的部分⽼⽼实实回答⾯试官的问题即可,通常需要问题运⽤到这个法则的是项⽬⾯,⽐如让你介绍⼀下你最得意的项⽬,回答问题的法则有 这⼏个要点:
项⽬背景: 简要说⼀下项⽬的背景,让⾯试官知道这个项⽬是做什么的个⼈⻆⾊: 让⾯试官知道你在这个项⽬中扮演的⻆⾊
难点: 让⾯试官知道你在项⽬开发过程中碰到的难点
解决⽅案: 针对上⾯的难点你有哪⼀些解决⽅案,是如何结合业务进⾏取舍的
总结沉淀: 在攻克上述的难点后有没有沉淀出⼀套通⽤的解决⽅案,有没有将⾃⼰的⽅案在⼤部⻔进⾏推⼴等等
重点就在于后⾯三条,也是最体现你个⼈综合素质的⼀部分,我是⾯试官的话会⾮常欣赏那种可以发现问题、找到多种⽅案、能对多种⽅案进⾏⽐对取舍还可以总结沉淀出通⽤解决⽅案回馈团队的⼈。
从上述⼏点可以体现出⼀个⼈的技术热情、解决问题的能⼒和总结提⾼的能⼒。
刻意引导
是的,在回答⾯试官提问的时候也可以做到刻意引导。我们就举⼏个简单的例⼦:
除了Vue还⽤过Angular吗? 这个时候很多候选⼈就很实诚回答「没有」,其实我们可以回答的更好,把你知道的说出来展示⾃⼰的能⼒才是最重要的,你可以说「我虽然没⽤过,但是在学习双向绑定原理的时候了解了⼀下Angular脏检查的原理,在学习Nestjs的时候了解了依赖注⼊的原理,跟Angular也是类似的」,⾯试官⼀定会接着 问你脏检查和依赖注⼊的问题,虽然你没有⽤过Angular,但是Angular的基本原理你都懂,这是很好的加分项,说明候选⼈有深⼊理解原理的意愿和触类旁通的能⼒
Vue如何实现双向绑定的? 很多候选⼈⽼⽼实实答了 object.defineproperty 如何如何操作,然后就没有了,其实你可以在回答完之后加上⼀嘴「Vue 3.0则选择了更好⽤的Proxy来替代object.defineproperty」或者「除了object.defineproperty这种数据劫持的⽅式,观察者模式和脏检查都可以实现双向绑定」,⾯试官⼤概率会问
「Proxy好在哪?」或者「聊聊脏检查」等等,这样下⼀个问题就会依然在你的可控范围内
我们第⼀个例⼦把本来回答不上来的问题,转化为了成功展示⾃⼰能⼒的加分项,第⼆个例⼦让⾃⼰更多的展示了⾃⼰的能⼒,⽽且始终使⾯试官的问题在⾃⼰的可控范围内。
向⾯试官提问
这个部分基本到了⾯试尾声了,属于做好了不影响⼤局,但是可能加分,如果做不好很容易踩雷的区域.
⾸先我们声明⼏个雷区:
切忌问结果: 问了也⽩问,绝⼤部分公司规定不会透露结果的,你这样让⼤家很尴尬
切忌问⼯资: 除了HR跟你谈⼯资的时候,千万别跟技术⾯试官谈⼯资,⼯资是所有公司的⾼压线,没法谈论切忌问技术问题: 别拿⾃⼰不会的技术难题反问⾯试官,完全没意义,⾯试官答也不是不答也不是
有⼏个⽐较好的提问可供参考:
如果我⼊职这个岗位的话,前三个⽉你希望我能做到些什么? 我的这个岗位的前任是为什么离职的,我什么地⽅能做的更好? 你对这个职位理想⼈选的要求是什么?
尽量围绕你的岗位进⾏提问,这可以使得你更快得熟悉你的⼯作内容,也让⾯试官看到你对此岗位的兴趣和热情,重要的是这些问题对于⾯试官⽽⾔既可以简略回答,也可以详细的给你讲解,如果他很热情得跟你介绍此岗位相关的情况,说明你可能表现得不错,否则的话,你可能不在他的备选名单⾥,这个时候就需要你早做打算了.
总结
我们⽤⼤量篇幅介绍了技术⾯试中的⼀些应试技巧,但是归根到底候选⼈的基本功和丰富的项⽬经验才是硬道理.
如果你看完了整篇⽂章,并进⾏了精⼼的准备,他是可以让你从75分到85分的实⽤技巧,⽽不是让你从55到85的什么秘籍.
⾯试官到底想看什么样的简历?
⾯试⼀直是程序员跳槽时期⾮常热⻔的话题,虽然现在已经过了跳槽的旺季,下⼀轮跳槽季需要到年底才会出现,但是当跳槽季的时候你再看这篇⽂章可能已经晚了,过冬的粮⻝永远不是冬天准备的,⽽是秋收的时候。
简历准备
简历是你进⼊⾯试的敲⻔砖,也是留给意向公司的第⼀印象,所以这个很重要,必须在这上⾯做⾜了⽂章,⼀份优秀的
⾯试简历是整个⾯试成败的重中之重,我们会详细分析如何准备简历才能保证简历不被刷掉。
简历通常有这⼏部分构成:
- 基本资料
- 专业技能
- ⼯作经历
- 项⽬经历
- 教育背景
我们会逐⼀进⾏分析。
准备简历模板
万事开头难,简历的编写如果从头开始需要浪费很多时间,其实最快速也最聪明的办法就是先找⼀份还不错的简历模板,之后我们只需要填写信息即可。
简历模板的选择很讲究,有些简历基本不看内容就会被刷掉,这些简历⼀般会对⾯试官进⾏视觉攻击,让简历给⾯试官的第⼀印象就是反感。
有两种坑爹的简历模板:
⼀种是经典简历模板,真是堪称『经典』,这种简历模板在我上⼩学的时候就有了,以现在的眼光看有点不够看了,配
⾊也⽐较『魔幻』,加上表格类的简历属于low到底端的简历类型,基本上扫⼀眼就扔了,这种简历只需要3秒钟就能被
⾯试官扔到垃圾堆。
另⼀种是设计感⼗⾜的简历模板,这种简历设计感⼗⾜,这五颜六⾊的配⾊⼀定能亮瞎⾯试官的双眼,这种花⾥胡哨的简历同样也是3秒钟沉到垃圾堆底部的简历。
以上两类简历模板堪称⾯试官杀⼿,我相信只要你⽤了上述两类模板,绝对连让⾯试官看第⼆眼的兴趣都没有。
⾯试官筛简历要的是⾼效、清晰、内容突出,不管是HR还是技术⾯试官都想在最快速的情况下看到有效信息,你眼中 所谓的『视觉效果』在别⼈眼⾥就是『视觉噪⾳』或者『视觉垃圾』,严重影响看简历的⼼情和寻找有效信息的速度。
其实我发现不仅仅是在互联⽹技术招聘这个领域,⼤部分企业招聘的简历要求都很简单,清晰、简洁即可,最重要的是要内容清晰,突出主题。
就像这样,颜⾊不超过⿊⽩灰三⾊,把强调的内容讲清楚,让⾯试官⼀眼就看到重点即可:
准备个⼈信息
个⼈信息部分主要包括姓名、电话、点⼦邮箱、求职意向,当然这四个是必填的,其它的都是选填,填好了是加分项, 否则很可能减分。
接下来才是重点:
- github:如果准备⼀个基本没有更新的博客或者没有任何贡献的github,那么给⾯试官⼀种为了放上去⽽放上去的 感觉,这基本上就是在跟⾯试官说『这个候选⼈平时根本没有总结提炼的习惯』,所以如果有⻓期维护的github或者博客⼀定要放上去,质量好的话会⾮常有⽤,如果没有千万别放。
- 学历:如果你的学历是专科、⾼中毕业之类的,还写在简历头部强调⼀遍,这就造成了你是『学渣』的印象,没有公司喜欢学渣的,这⼜增加了简历被刷的⼏率,如果是研究⽣以上学历可以写,突出⼀下学历优势,本科学历在技术⾯试领域基本上敲⻔砖级别的,没必要写。
- 年龄:如果你是⼤龄程序员,尤其是你还在求⼀份低端岗位的时候千万别写,⼀个⼤龄程序员在求职⼀个中低端岗位,说明这些年基本原地踏步,还不能加班,到这⾥基本上此简历就凉了⼀半了。
- 照⽚:形象优秀的可以贴,尤其是形象优秀的⼥程序媛,其它的最好不要贴,如果要贴的话,最好是贴那种PS过的⾮常职业的证件照,那种平时搞怪的、光着膀⼦的⽣活照,基本就是⾃杀⾏为。
如果你没有特别之处,直接按下⾯这种最简单的个⼈信息填写⽅式即可,切勿给⾃⼰加戏:
准备专业技能
对于程序员的专业技能其实就是技术栈,对于⾃⼰的技术栈如何描述是个很难的问题,⽐如什么算是精通?什么算是了解?什么是熟悉?
关于对技术技能的描述有很多种,有五种的也有三种的,⽽且每个⼈对词汇的理解都不⼀样,我结合相关专家的理解和
⾃⼰的理解来简单阐述下描述词汇的区别,我们这⾥只讲三种的了解、熟悉、精通。
了解:使⽤过某⼀项技术,能在别⼈指导下完成⼯作,但不能胜任复杂⼯作,也不能独⽴解决问题。
熟悉:⼤量运⽤过的某⼀项技术,能独⽴完成⼯作,且能独⽴完成有⼀定复杂度的⼯作,在技术的应⽤层⾯不会有太⼤问题,甚⾄理解⼀点原理。
精通:不仅可以运⽤某⼀⻔技术完成复杂项⽬,⽽且理解这项技术背后的原理,可以对此技术进⾏⼆次开发,甚⾄本身就是技术源码的贡献者。
我们就以Vue这个框架为例,如果你可以⽤vue写⼀些简单的⻚⾯,单独完成某⼏个⻚⾯的开发,但是⽆法脱离公司脚
⼿架⼯作,也⽆法独⽴从0完成⼀个有⼀定复杂度的项⽬,只能称之为了解。
如果你有⼤量运⽤vue的经验,有从0独⽴完成⼀定复杂度项⽬的能⼒,可以完全脱离脚⼿架进⾏开发,且对vue的原理有⼀定的了解,可以称之为熟悉。
如果你⽤vue完成过复杂度很⾼的项⽬,⽽且⾮常熟悉vue的原理,是vue源码的主要贡献者,亦或者根据vue源码进⾏过魔改(⽐如mpvue),你可以称得上精通。
那么有两个坑是候选⼈经常犯的,『杂』和『精』,这种两个坑⼤量集中在应届⽣和刚毕业每两年的新⼿身上,其主要特点是『急于表现⾃我』、『对技术深度与⼴度出现⽆知⽽导致的过度⾃信』。
⾸先说说杂,⽐如你要应聘⼀个Java后端,⽼⽼实实把⾃⼰的java技术栈写好就⾏了,强调⼀下⾃⼰擅⻓什么即可,最好专精某领域⽐如『⾼并发』、『⾼可⽤』等等,这个时候⼀些简历⾮要给⾃⼰加戏,⾃⼰会的不会的⼀股脑往上堆, 什么逆向、密码学、图形、驱动、AI都要体现出来,越杂越好,这种简历给⼈的印象就是个什么都不懂的半吊⼦。
再说说精,⼀个刚毕业的应届⽣,出来简历就各种精通,精通Java、精通Java虚拟机、精通spring全家桶、精通kafka 等等,请放⼼,这种简历是不会没头没脑投过来了,这种在⼤学⾥就精通各种的天才早被他的各种学⻓介绍进了⼤⼚或者外企做某某Star重点培养了,往往看到的这种也是半吊⼦。
再给⼤家⼀个技术栈模板:
这样写的后果就在于让⾯试官⼀眼就看出你是个吹⽜的半吊⼦,那些各种精通的全才在业界早就出名了,根本不可能还在投简历。
准备⼯作经历
⼯作经历本身不⽤花太多笔墨去写,⾯试官主要想看的就是每段⼯作经历的持续时间、在不同公司担任的职责如何、是否有⼤⼚的⼯作经验等等。
那么什么简历在这⾥给⾯试官减分呢?
频繁跳槽:⽐如三年换了四家公司,每个公司呆的时⻓不要超过⼀年常年初级岗:⽐如⼯作五六年之后依然在完成⼀些简单的项⽬开发
末流公司经历:在技术招聘届,⼤⼚的优先级最⾼⽐如BAT、TMD甚⾄微软、⾕歌等外企,知名度独⻆兽其次,⽐如商汤、旷视等等,⼀般的互联⽹公司排在第三,就是⼯作中⼩型的互联⽹公司⼀般⼤家叫不上名字,排在最后的就是外包和传统企业的经历
所以,如果你有频繁跳槽的经历怎么办?在本公司⽼⽼实实等到满⼀年再跳槽。
如果常年初级岗怎么办?想办法晋升或者参与⼀些业界知名项⽬,再或者写⼀个有⼀定复杂度的私⼈项⽬。
如果有末流公司经历怎么办?如果是很久以前的末流公司经验可以直接不写,也没⼈在乎你很早之前的⼯作经历,如果你现在就在末流公司,赶紧想办法跳槽,去不了⼤⼚,去⾮知名的互联⽹公司也算是胜利⼤逃亡了。
不建议任何形式的简历造假,如果去⼀些⼤⼚,分分钟背调出来,与其简历造假,不如现在就⾏动起来,⽐如从现在到年底跳槽季,深度参与⼀个知名开源项⽬或者做⼀个有⼀定复杂度的私⼈项⽬绰绰有余,除⾮996.
准备项⽬经历
项⽬经历不管对于社招还是校招都是重中之重,很多时候成败就在于项⽬经历这块,⼀个普通本科可以通过优秀的项⽬经历逆袭985,⼀个⼩⼚的员⼯也可以获得⼤⼚的⾯试机会。
但是必须要说⼀下项⽬经历的编写很讲究,这是为后⾯⾯试部分铺路的绝佳机会,也是直接让你的简历扑街的重点沦陷区域。
先说容易让简历扑街的⼏个坑位。
切忌流⽔账写法
项⽬经历流⽔账写法是绝⼤多数简历的通病,通篇下来就讲了⼀件事『我⼲了啥』。
⼤部分简历却是这样的:
⽤Vue、Vuex、Vue-router、axios等技术开发电商⽹站的前端部分,主要负责⾸⻚、店铺详情、商品详情、商品列表、订单详情、订单中⼼等相关⻚⾯的开发⼯作,与设计师与后端配合,可要⾼度还原设计稿。
这个描述有什么问题?
其实看似也没啥问题,但是这种流⽔账写法太多了,完全⽆法突出⾃⼰的优势展现⾃⼰的能⼒。
项⽬经历是考察重点,⾯试官想知道候选⼈在⼀次项⽬经历中扮演的⻆⾊、负责的模块、碰到的问题、解决的思路、达成的效果以及最后的总结与沉淀。
⽽上⾯的描述只显示了『我⼲了啥』,所以这种项⽬描述⼏乎是没意义的,因为对于⾯试官⽽⾔他看不到有效信息,没有有效信息的项⽬描述基本就没价值了,如果这个时候你还没有⼤⼚经历或者名校背书,基本上也就凉了。
切忌堆积项⽬
堆积项⽬这种现象往往出现在没有什么优秀项⽬经历的简历身上,候选⼈企图以数量优势掩盖质量的劣势,其实往往适得其反,项⽬经历的⼀栏最好放2-3个项⽬,⾮常优秀的项⽬可能放⼀个就⾜够了,举个极端例⼦如果有⼀天尤⾬溪写 简历,其实只需要在项⽬经历那些⼀⾏『Vue.js作者』就⾏了,当然,他并不需要投简历。
有⼀些项⽬切忌放上去:
demo级项⽬:很多简历居然还在放⼀些仿xx官⽹的demo,这是⼗⾜的减分项,有⼀些则是东拼⻄凑抄了⼀些框架的源码搞了个玩具项⽬,也没有任何价值。
烂⼤街的项⽬:这种以vue技术栈的为最,由于视频⽹站的某⻔课程流⾏,导致⼤量的仿饿了么、仿qq⾳乐、仿美团、仿去哪⼉,同样Java的同学也是仿电商⽹站、仿⼤众点评等等,⼗份简历5份⼀模⼀样的项⽬,你是⾯试官会怎么想。
低质量的开源项⽬:⼀个⼤原则就是低star的尽量别放(除⾮是⾼质量代码的冷⻔项⽬),⻓期弃坑的也不要放, 不要为了凑数量把低质量的项⽬暴露出来,好好藏着。
如果只放两个项⽬,最好的搭配是⼀个公司内部挑⼤梁的项⽬和⼀个社区内的开源项⽬,后者之所以可以占据⼀席之 地,是因为通过你的开源项⽬,⾯试官可以通过commit完整看到你的创造过程,⽐如⼯程化建设、commit规范、代码规范、协作⽅式、代码能⼒、沟通能⼒等等,这甚⾄⽐⾯试都有⽤,没有⽐开源项⽬更能展示你综合素质的东⻄了。
切忌放虚假项⽬
⼀个项⽬做没做过只要是有经验的⾯试官⼀问便知,如果你真的靠假项⽬忽悠过了⾯试,那这个公司⼋成也有问题,⼈才把关不过硬,你可以想象你的队友都是什么⽔平,在这种公司⼤成⻓价值也不⼤。
好,如果你说实在没项⽬可写了,我只能造假了,那么你应该想⼀下这多层追问。
⽐如你说你优化了⼀个前端项⽬的⾸屏性能,降低了⽩屏时间,那么⾯试官对这个性能优化问题会进⾏深挖,来考察候选⼈的实际⽔平:
- 你的性能优化指标是怎么确定的?平均下来时间减短了多少?
- 你的性能是如何测试的?有两种主流的性能测试⽅法你是怎么选的?
- 你是根据哪些指标进⾏针对性优化的?
- 除了你说的这些优化⽅法还有没有想过通过xx来解决?
- 你的这个优化⽅法在实际操作中碰到过什么问题吗?有没有进⼀步做过测试?
- 我们假设这么⼀种情况,⽐如xxxx,你会这么进⾏优化?
⾯试官多层追问的逻辑是这样的:
了解背景 -> 了解⽅案 -> 深挖⽅案 -> 模拟场景
⾸先得了解你性能优化的指标如何,接着需要了解你是这么测试的指标、再怎么进⾏针对性优化的,再接着提出⼀些其它解决⽅案考察你对优化场景的知识储备和⽅案决策能⼒,最后再模拟⼀个其它的业务场景,来考察你的技能迁移能
⼒,看看是否是对某块领域有⼀定的了解,⽽不是只针对某个项⽬。
如果要真的在⾯试现场对答如流,那么⼀定是在某⼀块领域有⼀定知识储备的⼈,不是随随便便搞个项⽬就能蒙混过关的。
合格的项⽬经历如何写
合格的项⽬经历必须要有以下⼏点: 项⽬概述
个⼈职责项⽬难点
⼯作成果
如果你不怕字太多,还可以选择性加⼊解决⽅案、选型思路等等,但是由于篇幅限制和为⾯试铺垫就不太建议写得太多。
项⽬概述的⽬的是让⾯试官理解项⽬,不是每个⼈⾯试官都做过你的那种项⽬,所以需⼀个简述⽅便⾯试官理解。
个⼈职责就是告诉⾯试官你在本项⽬中扮演的⻆⾊,是领导者?主导者?还是跟随者,你负责了哪些模块,承担了多⼤的⼯作量,以此来评估你在团队中的作⽤。
项⽬难点的⽬的在于让⾯试官看到你碰到的技术难题,⽅便后续⾯试对项⽬进⾏⼀系列讨论。
⼯作成果就很明显了,⾯试官需要看到你在做了上述⼯作到底达成了什么成绩,这个时候最好以数据说话,⽐如访问量、⽩屏时间等等。
像这种项⽬经历描述就⽐较合适:
这个时候也切忌展开⻓篇⼤论,把技术细节⼀个个写上去,甚⾄还写了⼼路历程的都是⼤忌,⼀⽅⾯篇幅太⼤会造成视觉混乱,另⼀⽅⾯⾯试官想看到的是『简』历,不是技术总结,⾯试官要⾯对上百份简历没那么时间来看你⻓篇⼤论,
⻓篇⼤论⼤可以在⾯试中展开。
最好的⽅法就是⼀⾏⽂字简单得说清楚即可,反正项⽬⾯的时候⼀定会问到,到时候好好把你准备的内容讲给⾯试官, 掌握⾯试的主动权就是从项⽬经历这⼀栏中开始。
教育背景
应届⽣可以写得更详细⼀点,⽐如绩点排名怎么样,有没有突出的科⽬,社招就不要写太多了,简单的⼊学时间、学校、专业即可,⽽且写你的最⾼学历即可,没必要从初中就开始写学历流⽔账,没有⼈看的。
⼏点注意事项
⾃我评价不建议写:技术⾯试⼏乎没⼈看你的⾃我评价,连⾯试技术问题都嫌『talk is cheap show me the code』,你的⾃我评价除了占篇幅没啥⽤处,充其量算是⾯试官的⼲扰信息。
简历封⾯千万别搞:这都是⼀些简历制作⽹站骗⽤户付费的伎俩,不仅是互联⽹⾏业,其它⾏业我也没⻅过要简历封⾯这种⽆⽤操作的。
证书不建议写:应届⽣可以酌情考虑弄个六级证书什么的,对于社招⽽⾔,列⼀堆证书甚⾄是减分项,国内的各种证你也懂的,是有多不⾃信才沦落到靠⼀堆证书来证明⾃⼰的价值。
千万别⽤技能图表:⾸先⽤90分、80分来评价⾃⼰的技术本身就没有什么说服⼒,也不可能这么精准,⽽且什么是90分、什么是80根本就没有⼀个公论,所以⽤⼀般的⽐较通⽤的熟悉、精通描述即可,千万别加戏,⾯试官或者 HR没那么多闲⼯夫去理解你的图表,⽼⽼实实按最通⽤⾼效的⽅式描述⾃⼰的技术栈。
简历最好⼀⻚:程序员⼜不是设计师有时候需要作品呈现,如果你的简历超过⼀⻚那么⼀定是出问题了,要么项
⽬、技术栈描述太多太杂占据⼤量篇幅,要么加了⼀堆图表或者图画来加戏,当然往往是犯前⼀个错误的更多。
这是我在⽹上找到的⼀个例⼦很能说明问题:
简历的版⾯⼨⼟⼨⾦,别说话跟裹脚布⼀样,精炼的⼀句话即可描述你的问题。
不建议⽤任何简历制作⽹站或者开源的简历制作器:我之前不仅⽤过上述的东⻄,还付过费,完全是浪费时间和浪费⾦钱,先说简历制作⽹站基本上都是那种花⾥胡哨的简历,看起来炫但是基本是⾯试官最讨厌的那种形式,开源的简历制作器也是类似的,我甚⾄还为了⾃⼰的简历魔改过这种制作器,到头来也是浪费时间,记住简历『⿊⽩ 灰』三个配⾊,简洁即可,切勿让简历形式喧宾夺主。
这是我整理的简历范本(项⽬经历可以多写⼀个):
你可能的疑问
如果你读到这⾥,谢谢你的耐⼼,可能你也会有疑问–『你这篇⽂章,这不让写,那不让写,我的简历填都填不满,怎么办?』。
实际上⼀份简历很多部分是已经固定了的,⽐如个⼈信息、教育背景、⼯作经历等等,其实能做⽂章的部分也只有技术栈和项⽬经历,也就是说后⾯两个部分是可以靠当下努⼒来改变的。
举个简单的例⼦,⽐如你做了3年的Java开发,公司还是⽤很⽼旧的SSM技术栈,⾃⼰其实有点沦为框架⼩⼦的意思, 只能做⼀些增删改查这种类型的⼯作,虽然⼯作内容都能胜任,但是根本做不了更有挑战性的事情,⽽外⾯对Java⼯程师的要求已经越来越⾼了.
我们完全可以花半年到⼀年的时间对某个细分领域进⾏专⻔的学习和实践,我们可以通过写私⼈项⽬、参与开源项⽬的
⽅式增加⾃⼰的项⽬经验和项⽬履历,⼀段时间后你肯定在某个细分领域⾄少处于⼀个进阶⽔平,你的简历也不可能填都填不满。
对于前端⼯程师也是⼀样,如果你觉得你逐渐沦为⻚⾯仔,⾃⼰也没有拿得出⼿的项⽬,也不妨多思考之前的项⽬是不是有的性能部分可以优化,是不是平时的⼯作有很多重复性的,能不能通过node⼯具或者vscode插件来提⾼效率,⼜ 或者公司的框架⽤起来太繁琐,可不可以进⾏改造升级提⾼⽣产⼒。
这个时候可能有⼈⼜问,『我⾃⼰⼯作都多的不⾏,凭什么还想为公司写什么⼯具框架?公司会额外付钱吗?』
你写的框架和⼯具是你未来跳槽中的简历的重要部分,即使它现在不会变现,在你跳槽过程中⼀定会变现,总之这些额外⼯作是为你⾃⼰打⼯的,你的现任公司只是因此额外受益了⽽已。
总结
我知道现在并不是跳槽的旺季,可能很多⼈不会看这篇⽂章,但是当真正跳槽季来临的时候,往往很多⼈⼜开始为填满
⾃⼰的简历⽽发愁,当⾃⼰的简历⽯沉⼤海,⼜会冒出这种⾔论:
哎呀,还是⾃⼰学历不够好,我能⼒没问题就是吃了学历的亏
⾃⼰没有⼤⼚的履历真是吃亏,⾃⼰能⼒没问题,就是没⼤⼚背书所在的公司都是⼀些⽼技术栈,我的简历就太吃亏了,都怪公司
实际情况是,⼤⼚履历、名校经历、出⾊项⽬只要有⼀项拿得出⼿,就会成为抢⼿货,更何况随着时间的推移,教育背景就越发不重要,更重要的还是⼯作履历和项⽬经历。
与其今后发愁如何填满简历,不如现在⾏动为⾃⼰的简历『打⼯』。
一、HTML和CSS
1、你做的页面在哪些浏览器测试过?这些浏览器的内核分别是什么?
IE: trident内核
Firefox:gecko内核
Safari:webkit内核
Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核
Chrome:Blink(基于webkit,Google与Opera Software共同开发)
2、每个HTML文件里开头都有个很重要的东西,Doctype,知道这是干什么的吗?
声明位于文档中的最前面的位置,处于 标签之前。此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范。(重点:告诉浏览器按照何种规范解析页面)
3、Quirks模式是什么?它和Standards模式有什么区别
从IE6开始,引入了Standards模式,标准模式中,浏览器尝试给符合标准的文档在规范上的正确处理达到在指定浏览器中的程度。
在IE6之前CSS还不够成熟,所以IE5等之前的浏览器对CSS的支持很差, IE6将对CSS提供更好的支持,然而这时的问题就来了,因为有很多页面是基于旧的布局方式写的,而如果IE6 支持CSS则将令这些页面显示不正常,如何在即保证不破坏现有页面,又提供新的渲染机制呢?
在写程序时我们也会经常遇到这样的问题,如何保证原来的接口不变,又提供更强大的功能,尤其是新功能不兼容旧功能时。遇到这种问题时的一个常见做法是增加参数和分支,即当某个参数为真时,我们就使用新功能,而如果这个参数 不为真时,就使用旧功能,这样就能不破坏原有的程序,又提供新功能。IE6也是类似这样做的,它将DTD当成了这个“参数”,因为以前的页面大家都不会去写DTD,所以IE6就假定 如果写了DTD,就意味着这个页面将采用对CSS支持更好的布局,而如果没有,则采用兼容之前的布局方式。这就是Quirks模式(怪癖模式,诡异模式,怪异模式)。
区别:
总体会有布局、样式解析和脚本执行三个方面的区别。
盒模型:在W3C标准中,如果设置一个元素的宽度和高度,指的是元素内容的宽度和高度,而在Quirks 模式下,IE的宽度和高度还包含了padding和border。
设置行内元素的高宽:在Standards模式下,给等行内元素设置wdith和height都不会生效,而在quirks模式下,则会生效。
设置百分比的高度:在standards模式下,一个元素的高度是由其包含的内容来决定的,如果父元素没有设置百分比的高度,子元素设置一个百分比的高度是无效的用margin:0 auto设置水平居中:使用margin:0 auto在standards模式下可以使元素水平居中,但在quirks模式下却会失效。
(还有很多,答出什么不重要,关键是看他答出的这些是不是自己经验遇到的,还是说都是看文章看的,甚至完全不知道。)
4、div+css的布局较table布局有什么优点?
改版的时候更方便 只要改css文件。
页面加载速度更快、结构化清晰、页面显示简洁。
表现与结构相分离。
易于优化(seo)搜索引擎更友好,排名更容易靠前。
5、 img的alt与title有何异同? strong与em的异同?
a:alt(alt text):为不能显示图像、窗体或applets的用户代理(UA),alt属性用来指定替换文字。替换文字的语言由lang属性指定。(在IE浏览器下会在没有title时把alt当成 tool tip显示)
title(tool tip):该属性为设置该属性的元素提供建议性的信息。
strong:粗体强调标签,强调,表示内容的重要性
em:斜体强调标签,更强烈强调,表示内容的强调点
6、你能描述一下渐进增强和优雅降级之间的不同吗?
渐进增强 progressive enhancement:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级 graceful degradation:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。
“优雅降级”观点
“优雅降级”观点认为应该针对那些最高级、最完善的浏览器来设计网站。而将那些被认为“过时”或有功能缺失的浏览器下的测试工作安排在开发周期的最后阶段,并把测试对象限定为主流浏览器(如 IE、Mozilla 等)的前一个版本。
在这种设计范例下,旧版的浏览器被认为仅能提供“简陋却无妨 (poor, but passable)” 的浏览体验。你可以做一些小的调整来适应某个特定的浏览器。但由于它们并非我们所关注的焦点,因此除了修复较大的错误之外,其它的差异将被直接忽略。
“渐进增强”观点
“渐进增强”观点则认为应关注于内容本身。
内容是我们建立网站的诱因。有的网站展示它,有的则收集它,有的寻求,有的操作,还有的网站甚至会包含以上的种种,但相同点是它们全都涉及到内容。这使得“渐进增强”成为一种更为合理的设计范例。这也是它立即被 Yahoo! 所采纳并用以构建其“分级式浏览器支持 (Graded Browser Support)”策略的原因所在。
那么问题来了。现在产品经理看到IE6,7,8网页效果相对高版本现代浏览器少了很多圆角,阴影(CSS3),要求兼容(使用图片背景,放弃CSS3),你会如何说服他?
7、为什么利用多个域名来存储网站资源会更有效?
CDN缓存更方便
突破浏览器并发限制
节约cookie带宽
节约主域名的连接数,优化页面响应速度
防止不必要的安全问题
8、请谈一下你对网页标准和标准制定机构重要性的理解。
网页标准和标准制定机构都是为了能让web发展的更‘健康’,开发者遵循统一的标准,降低开发难度,开发成本,SEO也会更好做,也不会因为滥用代码导致各种BUG、安全问题,最终提高网站易用性。
9、请描述一下cookies,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仅仅是为了在本地“存储”数据而生。
10、简述一下src与href的区别。
src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。
当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。
href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加
那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式。 11、知道的网页制作会用到的图片格式有哪些? png-8,png-24,jpeg,gif,svg。 但是上面的那些都不是面试官想要的最后答案。面试官希望听到是Webp。(是否有关注新技术,新鲜事物) 科普一下Webp:WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。Facebook Ebay等知名网站已经开始测试并使用WebP格式。 在质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小40% 12、知道什么是微格式吗?谈谈理解。在前端构建中应该考虑微格式吗? 微格式(Microformats)是一种让机器可读的语义化XHTML词汇的集合,是结构化数据的开放标准。是为特殊应用而制定的特殊格式。 优点:将智能数据添加到网页上,让网站内容在搜索引擎结果界面可以显示额外的提示。(应用范例:豆瓣,有兴趣自行google) 13、在css/js代码上线之后开发人员经常会优化性能,从用户刷新网页开始,一次js请求一般情况下有哪些地方会有缓存处理? 答案:dns缓存,cdn缓存,浏览器缓存,服务器缓存。 14、一个页面上有大量的图片(大型电商网站),加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验。 图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。 如果图片为css图片,可以使用CSSsprite,SVGsprite,Iconfont、Base64等技术。 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。 如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。 15、你如何理解HTML结构的语义化? 去掉或样式丢失的时候能让页面呈现清晰的结构: html本身是没有表现的,我们看到例如
是粗体,字体大小2em,加粗;是加粗的,不要认为这是html的表现,这些其实html默认的css样式在起作用,所以去掉或样式丢失的时候能让页面呈现清晰的结构不是语义化的HTML结构的优点,但是浏览器都有有默认样式,默认样式的目的也是为了更好的表达html的语义,可以说浏览器的默认样式和语义化的HTML结构是不可分割的。 屏幕阅读器(如果访客有视障)会完全根据你的标记来“读”你的网页. 例如,如果你使用的含语义的标记,屏幕阅读器就会“逐个拼出”你的单词,而不是试着去对它完整发音. PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对CSS的支持较弱) 使用语义标记可以确保这些设备以一种有意义的方式来渲染网页.理想情况下,观看设备的任务是符合设备本身的条件来渲染网页. 语义标记为设备提供了所需的相关信息,就省去了你自己去考虑所有可能的显示情况(包括现有的或者将来新的设备).例如,一部手机可以选择使一段标记了标题的文字以粗体显示.而掌上电脑可能会以比较大的字体来显示.无论哪种方式一旦你对文本标记为标题,您就可以确信读取设备将根据其自身的条件来合适地显示页面. 搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重 过去你可能还没有考虑搜索引擎的爬虫也是网站的“访客”,但现在它们他们实际上是极其宝贵的用户.没有他们的话,搜索引擎将无法索引你的网站,然后一般用户将很难过来访问. 你的页面是否对爬虫容易理解非常重要,因为爬虫很大程度上会忽略用于表现的标记,而只注重语义标记. 因此,如果页面文件的标题被标记,而不是,那么这个页面在搜索结果的位置可能会比较靠后.除了提升易用性外,语义标记有利于正确使用CSS和JavaScript,因为其本身提供了许多“钩钩”来应用页面的样式与行为. SEO主要还是靠你网站的内容和外部链接的。 便于团队开发和维护 W3C给我们定了一个很好的标准,在团队中大家都遵循这个标准,可以减少很多差异化的东西,方便开发和维护,提高开发效率,甚至实现模块化开发。 16、谈谈以前端角度出发做好SEO需要考虑什么? 了解搜索引擎如何抓取网页和如何索引网页 你需要知道一些搜索引擎的基本工作原理,各个搜索引擎之间的区别,搜索机器人(SE robot 或叫 web crawler)如何进行工作,搜索引擎如何对搜索结果进行排序等等。 Meta标签优化 主要包括主题(Title),网站描述(Description),和关键词(Keywords)。还有一些其它的隐藏文字比如Author(作者),Category(目录),Language(编码语种)等。 如何选取关键词并在网页中放置关键词 搜索就得用关键词。关键词分析和选择是SEO最重要的工作之一。首先要给网站确定主关键词(一般在5个上下),然后针对这些关键词进行优化,包括关键词密度(Density),相关度(Relavancy),突出性(Prominency)等等。 了解主要的搜索引擎 虽然搜索引擎有很多,但是对网站流量起决定作用的就那么几个。比如英文的主要有Google,Yahoo,Bing等;中文的有百度,搜狗,有道等。不同的搜索引擎对页面的抓取和索引、排序的规则都不一样。还要了解各搜索门户和搜索引擎之间的关系,比如AOL网页搜索用的是Google的搜索技术,MSN用的是Bing的技术。 主要的互联网目录 Open Directory自身不是搜索引擎,而是一个大型的网站目录,他和搜索引擎的主要区别是网站内容的收集方式不同。目录是人工编辑的,主要收录网站主页;搜索引擎是自动收集的,除了主页外还抓取大量的内容页面。 按点击付费的搜索引擎 搜索引擎也需要生存,随着互联网商务的越来越成熟,收费的搜索引擎也开始大行其道。最典型的有Overture和百度,当然也包括Google的广告项目Google Adwords。越来越多的人通过搜索引擎的点击广告来定位商业网站,这里面也大有优化和排名的学问,你得学会用最少的广告投入获得最多的点击。 搜索引擎登录 网站做完了以后,别躺在那里等着客人从天而降。要让别人找到你,最简单的办法就是将网站提交(submit)到搜索引擎。如果你的是商业网站,主要的搜索引擎和目录都会要求你付费来获得收录(比如Yahoo要299美元),但是好消息是(至少到目前为止)最大的搜索引擎Google目前还是免费,而且它主宰着60%以上的搜索市场。 链接交换和链接广泛度(Link Popularity) 网页内容都是以超文本(Hypertext)的方式来互相链接的,网站之间也是如此。除了搜索引擎以外,人们也每天通过不同网站之间的链接来Surfing(“冲浪”)。其它网站到你的网站的链接越多,你也就会获得更多的访问量。更重要的是,你的网站的外部链接数越多,会被搜索引擎认为它的重要性越大,从而给你更高的排名。 合理的标签使用 17、有哪项方式可以对一个DOM设置它的CSS样式? 外部样式表,引入一个外部css文件 内部样式表,将css代码放在 标签内部 内联样式,将css样式直接定义在 HTML 元素内部 18、CSS都有哪些选择器? 派生选择器(用HTML标签申明) id选择器(用DOM的ID申明) 类选择器(用一个样式类名申明) 属性选择器(用DOM的属性申明,属于CSS2,IE6不支持,不常用,不知道就算了) 除了前3种基本选择器,还有一些扩展选择器,包括 后代选择器(利用空格间隔,比如div .a{ }) 群组选择器(利用逗号间隔,比如p,div,#a{ }) 那么问题来了,CSS选择器的优先级是怎么样定义的? 基本原则: 一般而言,选择器越特殊,它的优先级越高。也就是选择器指向的越准确,它的优先级就越高。 复杂的计算方法: 用1表示派生选择器的优先级 用10表示类选择器的优先级 用100标示ID选择器的优先级 div.test1 .span var 优先级 1+10 +10 +1 span#xxx .songs li 优先级1+100 + 10 + 1 #xxx li 优先级 100 +1 那么问题来了,看下列代码,标签内的文字是什么颜色的? 123 答案:red。与样式定义在文件中的先后顺序有关,即是后面的覆盖前面的,与在
//方法二:未知元素的高宽
#div1{
width: 200px;
height: 200px;
background-color: #6699FF;
margin:auto;
position: absolute; //父元素需要相对定位
left: 0;
top: 0;
right: 0;
bottom: 0;
}
那么问题来了,如何垂直居中一个?(用更简便的方法。)
1
2
3
4
5
6 #container //的容器设置如下
{
display:table-cell;
text-align:center;
vertical-align:middle;
}
28、px和em的区别。
px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。
29、描述一个”reset”的CSS文件并如何使用它。知道normalize.css吗?你了解他们的不同之处?
重置样式非常多,凡是一个前端开发人员肯定有一个常用的重置CSS文件并知道如何使用它们。他们是盲目的在做还是知道为什么这么做呢?原因是不同的浏览器对一些元素有不同的默认样式,如果你不处理,在不同的浏览器下会存在必要的风险,或者更有戏剧性的性发生。
你可能会用Normalize来代替你的重置样式文件。它没有重置所有的样式风格,但仅提供了一套合理的默认样式值。既能让众多浏览器达到一致和合理,但又不扰乱其他的东西(如粗体的标题)。
在这一方面,无法做每一个复位重置。它也确实有些超过一个重置,它处理了你永远都不用考虑的怪癖,像HTML的audio元素不一致或line-height不一致。
30、Sass、LESS是什么?大家为什么要使用他们?
他们是CSS预处理器。他是CSS上的一种抽象层。他们是一种特殊的语法/语言编译成CSS。
例如Less是一种动态样式语言. 将CSS赋予了动态语言的特性,如变量,继承,运算, 函数. LESS 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可一在服务端运行 (借助 Node.js)。
为什么要使用它们?
结构清晰,便于扩展。
可以方便地屏蔽浏览器私有语法差异。这个不用多说,封装对浏览器语法差异的重复处理,减少无意义的机械劳动。
可以轻松实现多重继承。
完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。
31、display:none与visibility:hidden的区别是什么?
display : 隐藏对应的元素但不挤占该元素原来的空间。
visibility: 隐藏对应的元素并且挤占该元素原来的空间。
即是,使用CSS display:none属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”;而使用visibility:hidden属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在。
32、CSS中link和@import的区别是:
Link属于html标签,而@import是CSS中提供的
在页面加载的时候,link会同时被加载,而@import引用的CSS会在页面加载完成后才会加载引用的CSS
@import只有在ie5以上才可以被识别,而link是html标签,不存在浏览器兼容性问题
Link引入样式的权重大于@import的引用(@import是将引用的样式导入到当前的页面中)
33、简介盒子模型:
CSS的盒子模型有两种:IE盒子模型、标准的W3C盒子模型模型
盒模型:内容、内边距、外边距(一般不计入盒子实际宽度)、边框
34、为什么要初始化样式?
由于浏览器兼容的问题,不同的浏览器对标签的默认样式值不同,若不初始化会造成不同浏览器之间的显示差异
但是初始化CSS会对搜索引擎优化造成小影响
35、BFC是什么?
BFC(块级格式化上下文),一个创建了新的BFC的盒子是独立布局的,盒子内元素的布局不会影响盒子外面的元素。在同一个BFC中的两个相邻的盒子在垂直方向发生margin重叠的问题
BFC是指浏览器中创建了一个独立的渲染区域,该区域内所有元素的布局不会影响到区域外元素的布局,这个渲染区域只对块级元素起作用
36、html语义化是什么?
当页面样式加载失败的时候能够让页面呈现出清晰的结构
有利于seo优化,利于被搜索引擎收录(更便于搜索引擎的爬虫程序来识别)
便于项目的开发及维护,使html代码更具有可读性,便于其他设备解析。
37、Doctype的作用?严格模式与混杂模式的区别?
用于告知浏览器该以何种模式来渲染文档
严格模式下:页面排版及JS解析是以该浏览器支持的最高标准来执行
混杂模式:不严格按照标准执行,主要用来兼容旧的浏览器,向后兼容
38、IE的双边距BUG:块级元素float后设置横向margin,ie6显示的margin比设置的较大。解决:加入_display:inline
39、HTML与XHTML——二者有什么区别?
- 所有的标记都必须要有一个相应的结束标记
- 所有标签的元素和属性的名字都必须使用小写
- 所有的 XML 标记都必须合理嵌套
- 所有的属性必须用引号 “” 括起来
- 把所有 < 和 & 特殊符号用编码表示
- 给所有属性赋一个值
- 不要在注释内容中使用 “–”
- 图片必须有说明文字
40、html常见兼容性问题?
1.双边距BUG float引起的 使用display
2.3像素问题 使用float引起的 使用dislpay:inline -3px
3.超链接hover 点击后失效 使用正确的书写顺序 link visited hover active
4.Ie z-index问题 给父级添加position:relative
5.Png 透明 使用js代码 改
6.Min-height 最小高度 !Important 解决’
7.select 在ie6下遮盖 使用iframe嵌套
8.为什么没有办法定义1px左右的宽度容器(IE6默认的行高造成的,使用over:hidden,zoom:0.08 line-height:1px)
9.IE5-8不支持opacity,解决办法:
.opacity {
opacity: 0.4
filter: alpha(opacity=60); /* for IE5-7 /
-ms-filter: “progid:DXImageTransform.Microsoft.Alpha(Opacity=60)”; / for IE 8*/
} - IE6不支持PNG透明背景,解决办法: IE6下使用gif图片
41、对WEB标准以及W3C的理解与认识
答:标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索几率、使用外 链css和js脚本、结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件,容易维 护、改版方便,不需要变动页面内容、提供打印版本而不需要复制内容、提高网站易用性。
42、行内元素有哪些?块级元素有哪些?CSS的盒模型?
答:块级元素:div p h1 h2 h3 h4 form ul
行内元素: a b br i span input select
Css盒模型:内容,border ,margin,padding
43、前端页面有哪三层构成,分别是什么?作用是什么?
答:结构层 Html 表示层 CSS 行为层 js。
44、Doctype作用? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义?
(1)、 声明位于文档中的最前面,处于 标签之前。告知浏览器的解析器,用什么文档类型 规范来解析这个文档。
(2)、严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
(3)、在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
(4)、DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
45、行内元素有哪些?块级元素有哪些? 空(void)元素有那些?
(1)CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,比如div默认display属性值为“block”,成为“块级”元素;span默认display属性值为“inline”,是“行内”元素。
(2)行内元素有:a b span img input select strong(强调的语气) 块级元素有:div ul ol li dl dt dd h1 h2 h3 h4…p
(3)知名的空元素:
鲜为人知的是:
46、CSS的盒子模型?
(1)两种, IE 盒子模型、标准 W3C 盒子模型;IE 的content部分包含了 border 和 pading;
(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border).
47、CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?
* 1.id选择器( # myid)
2.类选择器(.myclassname)
3.标签选择器(div, h1, p)
4.相邻选择器(h1 + p)
5.子选择器(ul < li)
6.后代选择器(li a)
7.通配符选择器( * )
8.属性选择器(a[rel = “external”])
9.伪类选择器(a: hover, li: nth - child)
* 可继承: font-size font-family color, UL LI DL DD DT;
* 不可继承 :border padding margin width height ;
* 优先级就近原则,样式定义最近者为准;
* 载入样式以最后载入的定位为准;
优先级为:
!important > id > class > tag
important 比 内联优先级高
CSS3新增伪类举例:
p:first-of-type 选择属于其父元素的首个 元素的每个
元素。
p:last-of-type 选择属于其父元素的最后
元素的每个
元素。
p:only-of-type 选择属于其父元素唯一的
元素的每个
元素。
p:only-child 选择属于其父元素的唯一子元素的每个
元素。
p:nth-child(2) 选择属于其父元素的第二个子元素的每个
元素。
:enabled、:disabled 控制表单控件的禁用状态。
:checked,单选框或复选框被选中。
48、如何居中div,如何居中一个浮动元素?
给div设置一个宽度,然后添加margin:0 auto属性
div{
width:200px;
margin:0 auto;
}
居中一个浮动元素
确定容器的宽高 宽500 高 300 的层
设置层的外边距
.div {
Width:500px ; height:300px;//高度可以不设
Margin: -150px 0 0 -250px;
position:relative;相对定位
background-color:pink;//方便看效果
left:50%;
top:50%;
}
49、浏览器的内核分别是什么?经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用hack的技巧 ?
* IE浏览器的内核Trident、 Mozilla的Gecko、google的WebKit、Opera内核Presto;
* png24为的图片在iE6浏览器上出现背景,解决方案是做成PNG8.
* 浏览器默认的margin和padding不同。解决方案是加一个全局的\*{margin:0;padding:0;}来统一。
* IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。
浮动ie产生的双倍距离 #box{ float:left; width:10px; margin:0 0 0 100px;}
这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——\_display:inline;将其转化为行内属性。(\_这个符号只有ie6会识别)
渐进识别的方式,从总体中逐渐排除局部。
首先,巧妙的使用“\9”这一标记,将IE游览器从所有情况中分离出来。
接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。
css
.bb{
background-color:#f1ee18;/*所有识别*/
.background-color:#00deff\9; /*IE6、7、8识别*/
+background-color:#a200ff;/*IE6、7识别*/
\_background-color:#1e0bd1;/*IE6识别*/
}
* IE下,可以使用获取常规属性的方法来获取自定义属性,
也可以使用getAttribute()获取自定义属性;
Firefox下,只能使用getAttribute()获取自定义属性.
解决方法:统一通过getAttribute()获取自定义属性.
* IE下,even对象有x,y属性,但是没有pageX,pageY属性;
Firefox下,event对象有pageX,pageY属性,但是没有x,y属性.
* (条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
* Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决.
超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序:
L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
50、列出display的值,说明他们的作用。position的值, relative和absolute定位原点是?
10. block 象块类型元素一样显示。
none 缺省值。向行内元素类型一样显示。
inline-block 象行内元素一样显示,但其内容象块类型元素一样显示。
list-item 象块类型元素一样显示,并添加样式列表标记。
11. position的值
*absolute
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。
*fixed (老IE不支持)
生成绝对定位的元素,相对于浏览器窗口进行定位。
- relative
生成相对定位的元素,相对于其正常位置进行定位。 - static 默认值。没有定位,元素出现在正常的流中
*(忽略 top, bottom, left, right z-index 声明)。 - inherit 规定从父元素继承 position 属性的值。
51、absolute的containing block计算方式跟正常流有什么不同?
lock-level boxes
一个 block-level element (‘display’ 属性值为 ‘block’, ‘list-item’ 或是 ‘table’) 会生成一个 block-level box,这样的盒子会参与到 block-formatting context (一种布局的方式) 中。
block formatting context
在这种布局方式下,盒子们自所在的 containing block 顶部起一个接一个垂直排列,水平方向上撑满整个宽度 (除非内部的盒子自己内部建立了新的 BFC)。
containing block
一般来说,盒子本身就为其子孙建立了 containing block,用来计算内部盒子的位置、大小,而对内部的盒子,具体采用哪个 containing block 来计算,需要分情况来讨论:
若此元素为 inline 元素,则 containing block 为能够包含这个元素生成的第一个和最后一个 inline box 的 padding box (除 margin, border 外的区域) 的最小矩形;
否则则由这个祖先元素的 padding box 构成。
根元素所在的 containing block 被称为 initial containing block,在我们常用的浏览器环境下,指的是原点与 canvas 重合,大小和 viewport 相同的矩形;
对于 position 为 static 或 relative 的元素,其 containing block 为祖先元素中最近的 block container box 的 content box (除 margin, border, padding 外的区域);
对于 position:fixed 的元素,其 containing block 由 viewport 建立;
对于 position:absolute 的元素,则是先找到其祖先元素中最近的 position 属性非 static 的元素,然后判断:
如果都找不到,则为 initial containing block。
52、position跟display、margin collapse、overflow、float这些特性相互叠加后会怎么样?
www.cnblogs.com/jackyWHJ/p/…
53、css的基本语句构成是?
选择器{属性1:值1;属性2:值2;……}
54、浏览器标准模式和怪异模式之间的区别是什么?
盒子模型 渲染模式的不同
使用 window.top.document.compatMode 可显示为什么模式
55、说display属性有哪些?可以做什么?
display:block行内元素转换为块级元素
display:inline块级元素转换为行内元素
display:inline-block转为内联元素
56、哪些css属性可以继承?
可继承: font-size font-family color, ul li dl dd dt;
不可继承 :border padding margin width height ;
57、css优先级算法如何计算?
!important > id > class > 标签
!important 比 内联优先级高
*优先级就近原则,样式定义最近者为准;
*以最后载入的样式为准;
58、b标签和strong标签,i标签和em标签的区别?
后者有语义,前者则无。
59、有那些行内元素、有哪些块级元素、盒模型?
1.内联元素(inline element)
a – 锚点
abbr – 缩写
acronym – 首字
b – 粗体(不推荐)
big – 大字体
br – 换行
em – 强调
font – 字体设定(不推荐)
i – 斜体
img – 图片
input – 输入框
label – 表格标签
s – 中划线(不推荐)
select – 项目选择
small – 小字体文本
span – 常用内联容器,定义文本内区块
strike – 中划线
strong – 粗体强调
sub – 下标
sup – 上标
textarea – 多行文本输入框
tt – 电传文本
u – 下划线
var – 定义变量
2、块级元素
address – 地址
blockquote – 块引用
center – 举中对齐块
dir – 目录列表
div – 常用块级容易,也是css layout的主要标签
dl – 定义列表
fieldset – form控制组
form – 交互表单
h1 – 大标题
h2 – 副标题
h3 – 3级标题
h4 – 4级标题
h5 – 5级标题
h6 – 6级标题
hr – 水平分隔线
isindex – input prompt
menu – 菜单列表
noframes – frames可选内容,(对于不支持frame的浏览器显示此区块内容)
noscript – )可选脚本内容(对于不支持script的浏览器显示此内容)
ol – 排序表单
p – 段落
pre – 格式化文本
table – 表格
ul – 非排序列表
3.CSS盒子模型包含四个部分组成:
内容、填充(padding)、边框(border)、外边界(margin)。
60、有哪些选择符,优先级的计算公式是什么?行内样式和!important哪个优先级高?
#ID > .class > 标签选择符 !important优先级高
61.我想让行内元素跟上面的元素距离10px,加margin-top和padding-top可以吗?
margin-top,padding-top无效
62.CSS的盒模型由什么组成?
内容,border ,margin,padding
63、text-align:center和line-height有什么区别?
text-align是水平对齐,line-height是行间。
64、前端页面由哪三层构成,分别是什么?作用是什么?
结构层 Html 表示层 CSS 行为层 js
82、写一个表格以及对应的CSS,使表格奇数行为白色背景,偶数行为灰色,鼠标一上去为黄色背景。
表格
| 表格标题 | ||||
|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 |
| 1 | 2 | 3 | 4 | 5 |
| 1 | 2 | 3 | 4 | 5 |
二、JS基础 1、javascript的typeof返回哪些数据类型 object number function boolean underfind string typeof null;//object typeof isNaN;// typeof isNaN(123) typeof [];//object Array.isARRAY(); es5 toString.call([]);//”[object Array]” var arr=[]; arr.constructor;//Array 2、例举3种强制类型转换和2种隐式类型转换? 强制(parseInt,parseFloat,Number()) 隐式(==) 1==”1”//true null==undefined//true 3、split() join() 的区别 前者是切割成数组的形式, 后者是将数组转换成字符串 4、数组方法pop() push() unshift() shift() Push()尾部添加 pop()尾部删除 Unshift()头部添加 shift()头部删除 5、事件绑定和普通事件有什么区别 传统事件绑定和符合W3C标准的事件绑定有什么区别? div1.οnclick=function(){}; 1、如果说给同一个元素绑定了两次或者多次相同类型的事件,那么后面的绑定会覆盖前面的绑定 2、不支持DOM事件流 事件捕获阶段目标元素阶段=>事件冒泡阶段 addEventListener 1、 如果说给同一个元素绑定了两次或者多次相同类型的事件,所以的绑定将会依次触发 2、 支持DOM事件流的 3、 进行事件绑定传参不需要on前端 addEventListener(“click”,function(){},true);//此时的事件就是在事件冒泡阶段执行 ie9开始,ie11 edge:addEventListener ie9以前:attachEvent/detachEvent 1、 进行事件类型传参需要带上on前缀 2、 这种方式只支持事件冒泡,不支持事件捕获 事件绑定是指把事件注册到具体的元素之上,普通事件指的是可以用来注册的事件 6、IE和DOM事件流的区别 1.执行顺序不一样、 2.参数不一样 3.事件加不加on 4.this指向问题 IE9以前:attachEvent(“onclick”)、detachEvent(“onclick”) IE9开始跟DOM事件流是一样的,都是addEventListener 7、IE和标准下有哪些兼容性的写法 var ev = ev || window.event document.documentElement.clientWidth || document.body.clientWidth var target = ev.srcElement||ev.target 8、call和apply的区别 call和apply相同点: 都是为了用一个本不属于一个对象的方法,让这个对象去执行
toString.call([],1,2,3)
toString.apply([],[1,2,3])
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
9、b继承a的方法
考点:继承的多种方式
function b(){}
b.protoototype=new a;
10、JavaScript this指针、闭包、作用域
this:指向调用上下文
闭包:内层作用域可以访问外层作用域的变量
作用域:定义一个函数就开辟了一个局部作用域,整个js执行环境有一个全局作用域
11、事件委托是什么
符合W3C标准的事件绑定addEventLisntener /attachEvent
让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
12、闭包是什么,有什么特性,对页面有什么影响
闭包就是能够读取其他函数内部变量的函数。
闭包的缺点:滥用闭包函数会造成内存泄露,因为闭包中引用到的包裹函数中定义的变量都永远不会被释放,所以我们应该在必要的时候,及时释放这个闭包函数
13、如何阻止事件冒泡和默认事件
e. stopPropagation();//标准浏览器
event.canceBubble=true;//ie9之前
阻止默认事件:
为了不让a点击之后跳转,我们就要给他的点击事件进行阻止
return false
e.preventDefault();
14、添加 删除 替换 插入到某个接点的方法
obj.appendChild()
obj.insertBefore() //原生的js中不提供insertAfter();
obj.replaceChild()//替换
obj.removeChild()//删除
15、javascript的本地对象,内置对象和宿主对象
本地对象为array obj regexp等可以new实例化
内置对象为gload Math 等不可以实例化的
宿主为浏览器自带的document,window 等
16、document load 和document ready的区别
Document.onload 是在结构和样式加载完才执行js
window.onload:不仅仅要在结构和样式加载完,还要执行完所有的样式、图片这些资源文件,全部加载完才会触发window.onload事件
Document.ready原生种没有这个方法,jquery中有 $().ready(function)
17、””和“=”的不同
前者会自动转换类型
后者不会
1==”1”
null==undefined
===先判断左右两边的数据类型,如果数据类型不一致,直接返回false
之后才会进行两边值的判断
18、javascript的同源策略
一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合
http,ftp:协议
主机名;localhost
端口名:80:http协议的默认端口
https:默认端口是8083
同源策略带来的麻烦:ajax在不同域名下的请求无法实现,
如果说想要请求其他来源的js文件,或者json数据,那么可以通过jsonp来解决
19、编写一个数组去重的方法
var arr=[1,1,3,4,2,4,7];
=>[1,3,4,2,7]
一个比较简单的实现就是:
1、 先创建一个空数组,用来保存最终的结果
2、 循环原数组中的每个元素
3、 再对每个元素进行二次循环,判断是否有与之相同的元素,如果没有,将把这个元素放到新数组中
4、 返回这个新数组
function oSort(arr) {
var result ={};
var newArr=[];
for(var i=0;i<arr.length;i++){
if(!result[arr]) {
newArr.push(arr)
result[arr]=1
}
}
return newArr
}</arr.length;i++)
20、JavaScript是一门什么样的语言,它有哪些特点?
没有标准答案。
运行环境:浏览器中的JS引擎(v8.。。)
语言特性:面向对象,动态语言:
//动态语言的特性
var num=10;//num是一个数字类型
num=“jim”;//此时num又变成一个字符串类型
//我们把一个变量用来保存不同数据类型的语言称之为一个动态语言
//静态语言:c# java c c++
//静态语言在声明一个变量就已经确定了这个变量的数据类型,
// 而且在任何时候都不可以改变他的数据类型
javaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML网页上使用,用来给HTML网页增加动态功能。JavaScript兼容于ECMA标准,因此也称为ECMAScript。
基本特点
1.是一种解释性脚本语言(代码不进行预编译)。
2.主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。
3.可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
4.跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)。
21、JavaScript的数据类型都有什么?
基本数据类型:String,Boolean,number,undefined,object,Null
引用数据类型:Object(Array,Date,RegExp,Function)
那么问题来了,如何判断某变量是否为数组数据类型?
方法一.判断其是否具有“数组性质”,如slice()方法。可自己给该变量定义slice方法,故有时会失效
方法二.obj instanceof Array 在某些IE版本中不正确
方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法Array.isArray(), 保证其兼容性,最好的方法如下:
toString.call(18);//”[object Number]”
toString.call(“”);//”[object String]”
解析这种简单的数据类型直接通过typeof就可以直接判断
toString.call常用于判断数组、正则这些复杂类型
toString.call(/[0-9]{10}/)//”[object RegExp]”
if(typeof Array.isArray==="undefined"){
Array.isArray = function(arg){
return Object.prototype.toString.call(arg)==="[object Array]"
};
}
22、已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)
document.getElementById(“ID”).value
23、希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)
var domList = document.getElementsByTagName(‘input’)
var checkBoxList = [];//返回的所有的checkbox
var len = domList.length; //缓存到局部变量
while (len–) { //使用while的效率会比for循环更高
if (domList[len].type == ‘checkbox’) {
checkBoxList.push(domList[len]);
}
}
24、设置一个已知ID的DIV的html内容为xxxx,字体颜色设置为黑色(不使用第三方框架)
var dom = document.getElementById(“ID”);
dom.innerHTML = “xxxx”
dom.style.color = “#000”
25、当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
直接在DOM里绑定事件:
在JS里通过onclick绑定:xxx.onclick = test
通过事件添加进行绑定:addEventListener(xxx, ‘click’, test)
那么问题来了,Javascript的事件流模型都有什么?
“事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
26、看下列代码输出为何?解释原因。
var a;
alert(typeof a); // “undefined”
//alert(b); // 报错
b=10;
alert(typeof b);//”number”
解释:Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined。而b由于未声明将报错。注意未申明的变量和声明了未赋值的是不一样的。
undefined会在以下三种情况下产生:
1、 一个变量定义了却没有被赋值
2、 想要获取一个对象上不存在的属性或者方法:
3、 一个数组中没有被赋值的元素
注意区分undefined跟not defnied(语法错误)是不一样的
27、看下列代码,输出什么?解释原因。
var a = null;
alert(typeof a); //object
解释:null是一个只有一个值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回”object”。
28、看下列代码,输出什么?解释原因。
var undefined;//此时undefined这个变量的值是undefined
undefined == null; // true
1 == true; // true
此时会把布尔类型的值转换为数字类型 true=1 false=0
2 == true; // false
0 == false; // true
0 == ‘’; // true
NaN == NaN; // false
[] == false; // true
[] == ![]; // true
• undefined与null相等,但不恒等(=)
一个是number一个是string时,会尝试将string转换为number
尝试将boolean转换为number,0或1
尝试将Object转换成number或string,取决于另外一个对比量的类型
所以,对于0、空字符串的判断,建议使用 “=” 。“===”会先判断两边的值类型,类型不匹配时为false。
那么问题来了,看下面的代码,输出什么,foo的值为什么?
var foo = "11"+2-"1";
console.log(foo);//111
console.log(typeof foo);
执行完后foo的值为111,foo的类型为number。
29、看代码给答案。
var a = new Object();
a.value = 1;
b = a; {value:1}
b.value = 2;
alert(a.value);//2
答案:2(考察引用数据类型细节)
30、已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。
答案:alert(stringArray.join(“ ”))
已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”。
//
function combo(msg){
var arr=msg.split("-");//[get,element,by,id]
for(var i=1;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);//Element
}
msg=arr.join("");//msg=” getElementById”
return msg;
}
(考察基础API)
31、var numberArray = [3,6,2,4,1,5]; (考察基础API)
- 实现对该数组的倒排,输出[5,1,4,2,6,3]
- 实现对该数组的降序排列,输出[6,5,4,3,2,1]
function combo(msg){
var arr=msg.split("-");
for(var i=1;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);
}
msg=arr.join("");
return msg;
}
32、输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26
var d = new Date();
// 获取年,getFullYear()返回4位的数字
var year = d.getFullYear();
// 获取月,月份比较特殊,0是1月,11是12月
var month = d.getMonth() + 1;
// 变成两位
month = month < 10 ? ‘0’ + month : month;
// 获取日
var day = d.getDate();
day = day < 10 ? ‘0’ + day : day;
alert(year + ‘-’ + month + ‘-’ + day);
33、将字符串”{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲{name}”中的{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲替换成10,{name}替换成Tony (使用正则表达式)
答案:”{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲{id}_{name}”.replace(/{id}/g, ’10′).replace(/{$name}/g, ‘Tony’);
34、为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义
function escapeHtml(str) {
//[<>”&]:中括号中字符只要其中的一个出现就代表满足条件
//给replace第二个参数传递一个回调函数,回调函数中参数就是匹配结果,如果匹配不到就是null
return str.replace(/[<>”&]/g, function(match) {
switch (match) {
case “<”:
return “<”;
case “>”:
return “>”;
case “&”:
return “&”;
case “\””:
return “"”;
}
});
}
35、foo = foo||bar ,这行代码是什么意思?为什么要这样写?
这种写法称之为短路表达式
答案:if(!foo) foo = bar; //如果foo存在,值不变,否则把bar的值赋给foo。
短路表达式:作为”&&”和”||”操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
注意if条件的真假判定,记住以下是false的情况:
空字符串、false、undefined、null、0
36、看下列代码,将会输出什么?(变量声明提升)
var foo = 1;
function(){
console.log(foo);
var foo = 2;
console.log(foo);
}
答案:输出undefined 和 2。上面代码相当于:
var foo = 1;
function(){
var foo;
console.log(foo); //undefined
foo = 2;
console.log(foo); // 2;
}
函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分。
37、用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。
var iArray = [];
funtion getRandom(istart, iend){
var iChoice = istart - iend +1;
return Math.floor(Math.random() * iChoice + istart;
}
Math.random()就是获取0-1之间的随机数(永远获取不到1)
for(var i=0; i<10; i++){
var result= getRandom(10,100);
iArray.push(result);
}
iArray.sort();
38、把两个数组合并,并删除第二个元素。
var array1 = ['a','b','c'];
var bArray = [‘d’,‘e’,‘f’];
var cArray = array1.concat(bArray);
cArray.splice(1,1);
39、怎样添加、移除、移动、复制、创建和查找节点(原生JS,实在基础,没细写每一步)
1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
40、有这样一个URL:item.taobao.com/item.htm?a=…, b:’2′, c:”, d:’xxx’, e:undefined}。
答案:
function serilizeUrl(url) {
var urlObject = {};
if (/?/.test(url)) {
var urlString = url.substring(url.indexOf("?") + 1);
var urlArray = urlString.split("&");
for (var i = 0, len = urlArray.length; i < len; i++) {
var urlItem = urlArray[i];
var item = urlItem.split("=");
urlObject[item[0]] = item[1];
}
return urlObject;
}
return null;
}
41、正则表达式构造函数var reg=new RegExp(“xxx”)与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?
答案:当使用RegExp()构造函数的时候,不仅需要转义引号(即\”表示”),并且还需要双反斜杠(即\表示一个\)。使用正则表达字面量的效率更高。
邮箱的正则匹配:
var regMail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
24.看下面代码,给出输出结果。
for(var i=1;i<=3;i++){
setTimeout(function(){
console.log(i);
},0);
};
答案:4 4 4。
原因:Javascript事件处理器在线程空闲之前不会运行。追问,如何让上述代码输出1 2 3?
for(var i=1;i<=3;i++){
setTimeout((function(a){ //改成立即执行函数
console.log(a);
})(i),0);
};
1 //输出
2
3
42、写一个function,清除字符串前后的空格。(兼容所有浏览器)
使用自带接口trim(),考虑兼容性:
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+/, “”).replace(/\s+$/,"");
//\s匹配空白字符:回车、换行、制表符tab 空格
}
}
// test the function
var str = " \t\n test string ".trim();
alert(str == “test string”); // alerts “true”
43、Javascript中callee和caller的作用?
arguments.callee:获得当前函数的引用
caller是返回一个对函数的引用,该函数调用了当前函数;
callee是返回正在被执行的function函数,也就是所指定的function对象的正文。
那么问题来了?如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子?(使用callee完成)
var result=[];
function fn(n){ //典型的斐波那契数列
if(n1){
return 1;
}else if(n2){
return 1;
}else{
if(result[n]){
return result[n];
}else{
//argument.callee()表示fn()
result[n]=arguments.callee(n-1)+arguments.callee(n-2);
return result[n];
}
}
}
44、Javascript中, 以下哪条语句一定会产生运行错误? 答案( BC )
A、 var _变量=NaN;B、var 0bj = [];C、var obj = //; D、var obj = {};
//正确答案:BC
45、以下两个变量a和b,a+b的哪个结果是NaN? 答案( C )
A、var a=undefind; b=NaN //拼写
B、var a=‘123’; b=NaN//字符串
C、var a =undefined , b =NaN
D、var a=NaN , b=‘undefined’//”Nan”
//var a=10; b=20; c=4; ++b+c+a++
//21+4+10=35;
46、var a=10; b=20; c=4; ++b+c+a++ 以下哪个结果是正确的?答案( B )
A、 34 B、35 C、36 D、37
47、下面的JavaScript语句中,( D )实现检索当前页面中的表单元素中的所有文本框,并将它们全部清空
A. for(vari=0;i< form1.elements.length;i++) {
if(form1.elements.type==”text”)
form1.elements.value=”";}
B. for(vari=0;i<document.forms.length;i++) {
if(forms[0].elements.type==”text”)
forms[0].elements.value=”";
}
C. if(document.form.elements.type==”text”)
form.elements.value=”";
D. for(vari=0;i<document.forms.length; i++){
for(var j=0;j<document.forms.elements.length; j++){
if(document.forms.elements[j].type==”text”)
document.forms.elements[j].value=”";
}
}
48、要将页面的状态栏中显示“已经选中该文本框”,下列JavaScript语句正确的是( A )
A. window.status=”已经选中该文本框”
B. document.status=”已经选中该文本框”
C. window.screen=”已经选中该文本框”
D. document.screen=”已经选中该文本框”
49、以下哪条语句会产生运行错误:(A)正确答案:A、D
A.var obj = ();B.var obj = [];C.var obj = {};D.var obj = //;
50、以下哪个单词不属于javascript保留字:(B)
A.with B.parent C.class D.void
51、请选择结果为真的表达式:(C)
A.null instanceof Object B.null === undefined C.null == undefined D.NaN == NaN
52、Javascript中, 如果已知HTML页面中的某标签对象的id=”username”,用____document.getElementById(‘username’)___ 方法获得该标签对象。
53、typeof运算符返回值中有一个跟javascript数据类型不一致,它是_______”function”_________。
typeof Number
typeof Object
54、定义了一个变量,但没有为该变量赋值,如果alert该变量,javascript弹出的对话框中显示___undefined______ 。
55、分析代码,得出正确的结果。
var a=10, b=20 , c=30;
++a;
a++;
e=++a+(++b)+(c++)+a++;
alert(e);
弹出提示对话框:77
var a=10, b=20 , c=30;
++a;//a=11
a++;//a=11
e=++a+(++b)+(c++)+a++;
//a=12 13+21+30+13=77
alert(e);
56、写出函数DateDemo的返回结果,系统时间假定为今天
function DateDemo(){
var d, s=“今天日期是:”;
d = new Date();
s += d.getMonth() + “/”;
s += d.getDate() + “/”;
s += d.getFullYear();
return s;}
结果:今天日期是:7/17/2010
57、写出程序运行的结果?
for(i=0, j=0; i<10, j<6; i++, j++){
k = i + j;}
结果:10
for(i=0, j=0; i<10, j<6; i++, j++){
//j=5 i=5
k = i + j;//k=10
}
//结果:10
58、阅读以下代码,请分析出结果:
var arr = new Array(1 ,3 ,5);
arr[4]=‘z’;//[1,3,5,undefined,’z’]
arr2 = arr.reverse();//arr2=[’z’,undefined,5,3,1];
//arr=[’z’,undefined,5,3,1]
arr3 = arr.concat(arr2);
alert(arr3);
弹出提示对话框:z,5,3,1,z,5,3,1
reverse 方法颠倒数组中元素的位置,并返回该数组的引用。
59、补充按钮事件的函数,确认用户是否退出当前页面,确认之后关闭窗口;
60、写出简单描述html标签(不带属性的开始标签和结束标签)的正则表达式,并将以下字符串中的html标签去除掉 var str = “
这里是div 里面的段落
”; // var str = “
这里是div 里面的段落
”;
alert(str.replace(reg,”"));
61、完成foo()函数的内容,要求能够弹出对话框提示当前选中的是第几个单选框。
第三种(函数对象方式):
var sum3 = new Function(“num1”,“num2”,“return num1+num2”);
69、Javascript如何实现继承?
原型链继承,借用构造函数继承,组合继承,寄生式继承,寄生组合继承
72、Javascript创建对象的几种方式?
工厂方式,构造函数方式,原型模式,混合构造函数原型模式,动态原型方式
73、把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?
如果说放在body的封闭之前,将会阻塞其他资源的加载
如果放在body封闭之后,不会影响body内元素的加载
74、iframe的优缺点?
优点:
- 解决加载缓慢的第三方内容如图标和广告等的加载问题
- Security sandbox
- 并行加载脚本
缺点: - iframe会阻塞主页面的Onload事件
- 即时内容为空,加载也需要时间
- 没有语意
75、请你谈谈Cookie的弊端?
缺点:
1.Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
76、DOM操作——怎样添加、移除、移动、复制、创建和查找节点。 - 创建新节点
createDocumentFragment() // 创建一个DOM片段
createElement() // 创建一个具体的元素
createTextNode() // 创建一个文本节点 - 添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() // 在已有的子节点前插入一个新的子节点 - 查找
getElementsByTagName() // 通过标签名称
getElementsByName() // 通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() // 通过元素Id,唯一性
77、js延迟加载的方式有哪些? - defer和async
- 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
- 按需异步载入js
78、documen.write和 innerHTML 的区别?
document.write 只能重绘整个页面
innerHTML 可以重绘页面的一部分
79、哪些操作会造成内存泄漏?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。 - setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
- 闭包
- 控制台日志
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
83、判断一个字符串中出现次数最多的字符,统计这个次数
答:var str = ‘asdfssaaasasasasaa’;
var json = {};
for (var i = 0; i < str.length; i++) {
if(!json[str.charAt(i)]){
json[str.charAt(i)] = 1;
}else{
json[str.charAt(i)]++;
}
};
var iMax = 0;
var iIndex = ‘’;
for(var i in json){
if(json[i]>iMax){
iMax = json[i];
iIndex = i;
}
}
alert(‘出现次数最多的是:’+iIndex+‘出现’+iMax+‘次’);
93、写一个获取非行间样式的函数
function getStyle(obj,attr,value)
{
if(!value)
{
if(obj.currentStyle)//ie
{
return obj.currentStyle(attr);
}
else{//标准浏览器
obj.getComputedStyle(attr,false);
}
}
else
{
obj.style[attr] = value;
}
}
94、解释jsonp的原理,以及为什么不是真正的ajax
Jsonp并不是一种数据格式,而json是一种数据格式,jsonp是用来解决跨域获取数据的一种解决方案,具体是通过动态创建script标签,然后通过标签的src属性获取js文件中的js脚本,该脚本的内容是一个函数调用,参数就是服务器返回的数据,为了处理这些返回的数据,需要事先在页面定义好回调函数,本质上使用的并不是ajax技术
99、字符串反转,如将 ‘12345678’ 变成 ‘87654321’
//大牛做法;
//思路:先将字符串转换为数组 split(),利用数组的反序函数 reverse()颠倒数组,再利用 jion() 转换为字符串
var str = ‘12345678’;
str = str.split(’’).reverse().join(’’);
100、将数字 12345678 转化成 RMB形式 如: 12,345,678
//个人方法;
//思路:先将数字转为字符, str= str + ‘’ ;
//利用反转函数,每三位字符加一个 ','最后一位不加; re()是自定义的反转函数,最后再反转回去!
for(var i = 1; i <= re(str).length; i++){
tmp += re(str)[i - 1];
if(i % 3 == 0 && i != re(str).length){
tmp += ‘,’;
}
}
101、生成5个不同的随机数;
//思路:5个不同的数,每生成一次就和前面的所有数字相比较,如果有相同的,则放弃当前生成的数字!
var num1 = [];
for(var i = 0; i < 5; i++){
num1[i] = Math.floor(Math.random()*10) + 1; //范围是 [1, 10]
for(var j = 0; j < i; j++){
if(num1[i] == num1[j]){
i–;
}
}
}
102、去掉数组中重复的数字 方法一;
//思路:每遍历一次就和之前的所有做比较,不相等则放入新的数组中!
//这里用的原型 个人做法;
Array.prototype.unique = function(){
var len = this.length,
newArr = [],
flag = 1;
for(var i = 0; i < len; i++, flag = 1){
for(var j = 0; j < i; j++){
if(this[i] == this[j]){
flag = 0; //找到相同的数字后,不执行添加数据
}
}
flag ? newArr.push(this[i]) : ‘’;
}
return newArr;
}
方法二:
(function(arr){
var len = arr.length,
newArr = [],
flag;
for(var i = 0; i < len; i+=1, flag = 1){
for(var j = 0; j < i; j++){
if(arr[i] == arr[j]){
flag = 0;
}
}
flag?newArr.push(arr[i]):’’;
}
alert(newArr);
})([1, 1, 22, 3, 4, 55, 66]);
103、阶乘函数;98765…*1
//原型方法
Number.prototype.N = function(){
var re = 1;
for(var i = 1; i <= this; i++){
re *= i;
}
return re;
}
var num = 5;
alert(num.N());
104、window.location.search返回的是什么?
答:查询(参数)部分。除了给动态语言赋值以外,我们同样可以给静态页面,并使用javascript来获得相信应的参数值
返回值:?ver=1.0&id=timlq 也就是问号后面的!
//url:www.sina.com/getage?numb…
105、window.location.hash 返回的是什么?
答:锚点 , 返回值:#love ;
//url:www.sina.com/getage?#age
这时就返回”#age”
106、window.location.reload() 作用?
答:刷新当前页面。
107、阻止冒泡函数
function stopPropagation(e) {
e = e || window.event;
if(e.stopPropagation) { //W3C阻止冒泡方法
e.stopPropagation();
} else {
e.cancelBubble = true; //IE阻止冒泡方法
}
}
document.getElementById(‘need_hide’).onclick = function(e) {
stopPropagation(e);
}
108、什么是闭包? 写一个简单的闭包?;
答:我的理解是,闭包就是能够读取其他函数内部变量的函数。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
function outer(){
var num = 1;
function inner(){
var n = 2;
alert(n + num);
}
return inner;
}
outer()();
109、javascript 中的垃圾回收机制?
答:在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再 被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么 函数a执行后不会被回收的原因。
110、看题做答:
function f1(){
var tmp = 1;
this.x = 3;
console.log(tmp); //A
console.log(this.x); //B
}
var obj = new f1(); //1
console.log(obj.x) //2
console.log(f1()); //3
分析:
这道题让我重新认识了对象和函数,首先看代码(1),这里实例话化了 f1这个类。相当于执行了 f1函数。所以这个时候 A 会输出 1, 而 B 这个时候的 this 代表的是 实例化的当前对象 obj B 输出 3.。 代码(2)毋庸置疑会输出 3, 重点 代码(3)首先这里将不再是一个类,它只是一个函数。那么 A输出 1, B呢?这里的this 代表的其实就是window对象,那么this.x 就是一个全局变量 相当于在外部 的一个全局变量。所以 B 输出 3。最后代码由于f没有返回值那么一个函数如果没返回值的话,将会返回 underfined ,所以答案就是 : 1, 3, 3, 1, 3, underfined 。
111、下面输出多少?
var o1 = new Object();
var o2 = o1;
o2.name = “CSSer”;
console.log(o1.name);
如果不看答案,你回答真确了的话,那么说明你对javascript的数据类型了解的还是比较清楚了。js中有两种数据类型,分别是:基本数据类型和引用数据类型(object Array)。对于保存基本类型值的变量,变量是按值访问的,因为我们操作的是变量实际保存的值。对于保存引用类型值的变量,变量是按引用访问的,我们操作的是变量值所引用(指向)的对象。答案就清楚了: //CSSer;
112、再来一个
function changeObjectProperty (o) {
o.siteUrl = “www.csser.com/”;
o = new Object();
o.siteUrl = “www.popcg.com/”;
}
var CSSer = new Object();
changeObjectProperty(CSSer);
console.log(CSSer.siteUrl); //
如果CSSer参数是按引用传递的,那么结果应该是"www.popcg.com/",但实际结果却仍是"…
(补充:内部环境可以通过作用域链访问所有的外部环境中的变量对象,但外部环境无法访问内部环境。每个环境都可以向上搜索作用域链,以查询变量和函数名,反之向下则不能。)
113、输出多少?
var a = 6;
setTimeout(function () {
var a = 666;//由于变量a是一个局部变量
alert(a); // 输出666,
}, 1000);
a = 66;
因为var a = 666;定义了局部变量a,并且赋值为666,根据变量作用域链,
全局变量处在作用域末端,优先访问了局部变量,从而覆盖了全局变量 。
var a = 6;
setTimeout(function () {
//变量声明提前
alert(a); // 输出undefined
var a = 666;
}, 1000);
a = 66;
因为var a = 666;定义了局部变量a,同样覆盖了全局变量,但是在alert(a);之前
a并未赋值,所以输出undefined。
var a = 6;
setTimeout(function(){
alert(a);
var a = 66;
}, 1000);
a = 666;
alert(a);
//结果:666 undefined
记住: 异步处理,一切OK 声明提前
114、输出多少?
function setN(obj){
obj.name=‘屌丝’;
obj = new Object();
obj.name = ‘腐女’;
};
var per = new Object();
setN(per);
alert(per.name); //屌丝 内部
115、JS的继承性
window.color = ‘red’;
var o = {color: ‘blue’};
function sayColor(){
alert(this.color);
}
考点:1、this的指向
2、call的用法
sayColor(); //red
sayColor.call(this); //red this指向的是window对象
sayColor.call(window); //red
sayColor.call(o); //blue
116、精度问题: JS 精度不能精确到 0.1 所以 。。。。同时存在于值和差值中
var n = 0.3,m = 0.2, i = 0.2, j = 0.1;
alert((n - m) == (i - j)); //false
alert((n-m) == 0.1); //false
alert((i-j)==0.1); //true
117、加减运算
alert(‘5’+3); //53 string
alert(‘5’+‘3’); //53 string
alert(‘5’-3); //2 number
alert(‘5’-‘3’); //2 number
118、什么是同源策略?
指: 同协议、端口、域名的安全策略,由网景(Netscape)公司提出来的安全协议!
120、为什么不能定义1px左右的div容器?
IE6下这个问题是因为默认的行高造成的,解决的方法也有很多,例如:
overflow:hidden | zoom:0.08 | line-height:1px
121、结果是什么?
function foo(){
foo.a = function(){alert(1)};
this.a = function(){alert(2)};
a = function(){alert(3)};
var a = function(){alert(4)};
};
foo.prototype.a = function(){alert(5)};
foo.a = function(){alert(6)};
foo.a(); //6
var obj = new foo();
obj.a(); //2
foo.a(); //1
122、输出结果
var a = 5;
function test(){
a = 0;
alert(a);
alert(this.a); //没有定义 a这个属性
var a;
alert(a)
}
test(); // 0, 5, 0
new test(); // 0, undefined, 0 //由于类它自身没有属性a, 所以是undefined
123、计算字符串字节数:
new function(s){
if(!arguments.length||!s) return null;
if(""==s) return 0; //无效代码,因为上一句!s已经判断过
var l=0;
for(var i=0;i<s.length;i++){
if(s.charCodeAt(i)>255) l+=2; else l+=1; //charCodeAt()得到的是unCode码
} //汉字的unCode码大于 255bit 就是两个字节
alert(l);
}(“hello world!”);
124、结果是:
var bool = !!2; alert(bool);//true;
技巧:双向非操作可以把字符串和数字转换为布尔值。
125、声明对象,添加属性,输出属性
var obj = {
name: ‘leipeng’,
showName: function(){
alert(this.name);
}
}
obj.showName();
126、匹配输入的字符:第一个必须是字母或下划线开头,后面就是字母和数字或者下划线构成,长度5-20
var reg = /1[a-zA-Z0-9_]{4,19}/,
name1 = ‘leipeng’,
name2 = ‘0leipeng’,
name3 = ‘你好leipeng’,
name4 = ‘hi’;
alert(reg.test(name1));
alert(reg.test(name2));
alert(reg.test(name3));
alert(reg.test(name4));
127、检测变量类型
function checkStr(str){
typeof str == ‘string’? alert(‘true’):alert(‘false’);
}
checkStr(‘leipeng’);
128、如何在HTML中添加事件,几种方法?
1、标签之中直接添加 οnclick=“fun()”;
2、JS添加 Eobj.onclick = method;
3、现代事件 IE9以前: obj.attachEvent(‘onclick’, method);
标准浏览器: obj.addEventListener(‘click’, method, false);
129、BOM对象有哪些,列举window对象?
1、window对象 ,是JS的最顶层对象,其他的BOM对象都是window对象的属性;
2、document对象,文档对象;
3、location对象,浏览器当前URL信息;
4、navigator对象,浏览器本身信息;
5、screen对象,客户端屏幕信息;
6、history对象,浏览器访问历史信息;
130、请问代码实现 outerHTML
//说明:outerHTML其实就是innerHTML再加上本身;
Object.prototype.outerHTML = function(){
var innerCon = this.innerHTML, //获得里面的内容
outerCon = this.appendChild(innerCon); //添加到里面
alert(outerCon);
}
演示代码:
Document
hello
131、JS中的简单继承 call方法! //顶一个父母类,注意:类名都是首字母大写的哦! function Parent(name, money){ this.name = name; this.money = money; this.info = function(){ alert('姓名: '+this.name+' 钱: '+ this.money); } } //定义孩子类 function Children(name){ Parent.call(this, name); //继承 姓名属性,不要钱。 this.info = function(){ alert('姓名: '+this.name); } } //实例化类 var per = new Parent('parent', 800000000000); var chi = new Children('child'); per.info(); chi.info(); 132、bind(), live(), delegate()的区别 bind: 绑定事件,对新添加的事件不起作用,方法用于将一个处理程序附加到每个匹配元素的事件上并返回jQuery对象。 live: 方法将一个事件处理程序附加到与当前选择器匹配的所有元素(包含现有的或将来添加的)的指定事件上并返回jQuery对象。 delegate: 方法基于一组特定的根元素将处理程序附加到匹配选择器的所有元素(现有的或将来的)的一个或多个事件上。
最佳实现:on() off()
133、typeof 的返回类型有哪些?
alert(typeof [1, 2]); //object
alert(typeof ‘leipeng’); //string
var i = true;
alert(typeof i); //boolean
alert(typeof 1); //number
var a;
alert(typeof a); //undefined
function a(){;};
alert(typeof a) //function
134、简述link和import的区别?
区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。
135、window.onload 和 document.ready的区别?
load要等到图片和包含的文件都加在进来之后执行;
ready是不包含图片和非文字文件的文档结构准备好就执行;
136、 解析URL成一个对象?
String.prototype.urlQueryString = function(){
var url = this.split(’?’)[1].split(’&’),
len = url.length;
this.url = {};
for(var i = 0; i < len; i += 1){
var cell = url[i].split('='),
key = cell[0],
val = cell[1];
this.url[''+key+''] = val;
}
return this.url;
}
var url = '?name=12&age=23';
console.log(url.urlQueryString().age);
137、看下列代码输出什么?
var foo = “11”+2-“1”;
console.log(foo);
console.log(typeof foo);
执行完后foo的值为111,foo的类型为Number。
138、看下列代码,输出什么?
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
执行完后输出结果为2
139、已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。
答案:alert(stringArray.join(” “))
140、已知有字符串foo=“get-element-by-id”,写一个function将其转化成驼峰表示法"getElementById”。
答案:function combo(msg){
var arr = msg.split(”-”);
var len = arr.length; //将arr.length存储在一个局部变量可以提高for循环效率
for(var i=1;i<len;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);
}
msg=arr.join(”");
return msg;
}
142、原生JS的window.onload与Jquery的(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
143、你如何优化自己的代码?
代码重用
避免全局变量(命名空间,封闭空间,模块化mvc…)
拆分函数避免函数过于臃肿:单一职责原则
适当的注释,尤其是一些复杂的业务逻辑或者是计算逻辑,都应该写出这个业务逻辑的具体过程
内存管理,尤其是闭包中的变量释放
144、请描述出下列代码运行的结果
function d(){
console.log(this);
}
d();//window
145、需要将变量e的值修改为“a+b+c+d”,请写出对应的代码
var e=”abcd”;
设计一段代码能够遍历下列整个DOM节点
146、怎样实现两栏等高? Title
内容
内容
内容
内容
内容
内容
内容
147、使用js实现这样的效果:在文本域里输入文字时,当按下enter键时不换行,而是替换成“{{enter}}”,(只需要考虑在行尾按下enter键的情况). textarea.οnkeydοwn=function(e){ e.preventDefault();//为了阻止enter键的默认换行效果 if(e.keycode==”enter键码”){ testarea.value+=”{{enter}}”; } } 148、以下代码中end字符串什么时候输出 var t=true; setTimeout(function(){ console.log(123); t=false; },1000); while(t){}// 此时是一个死循环,永远不可能执行setTimeout中的回调函数 console.log(‘end’); 149、specify(‘hello,world’)//=>’h,e,l,l,o,w,o,r,l,d’实现specify函数 function specify(str){ var tempArray = Array.prototype.filter.call(str,function(value,index,array){ return value >= 'A' && value <= 'z' && value != "_"; }); return tempArray.join(","); } console.log(specify(“hedd____df*(%$#a !!!))))))llo,Wo@@@r ld”)); //h,e,l,l,o,W,o,r,l,d
150、请将一个URL的search部分参数与值转换成一个json对象
//search部分的参数格式:a=1&b=2&c=3
function getJsonFromUrlSearch(search){
var item;
var result={};
if(search.indexOf(’&’)<0){
item=search.split(’=’);
result[item[0]]=item[1];
return result;
}
var splitArray=search.split(’&’);
for (var i = 0; i < splitArray.length; i++) {
var obj = splitArray[i];
item=obj.split(’=’);
result[item[0]]=item[1];
}
return result;
}
var c=getJsonFromUrlSearch(“a=1&b=2&c=3”);
151、请用原生js实现jquery的get\post功能,以及跨域情况下
152、请简要描述web前端性能需要考虑哪方面,你的优化思路是什么?
//参见雅虎14web优化规则
//减少http请求:
//1、小图弄成大图,2、合理的设置缓存
//3、资源合并、压缩
//将外部的js文件置底
153、简述readyonly与disabled的区别
readonly只针对input(text / password)和textarea有效,
而disabled对于所有的表单元素都有效,当表单元素在使用了disabled后,当我们将表单以POST或GET的方式提交的话,这个元素的值不会被传递出去,而readonly会将该值传递出去
155、编写一个方法,去掉一个数组的复重元素
156、写出3个使用this的典型应用
构造函数中使用this,原型中使用this,对象字面量使用this
157、请尽可能详尽的解释ajax的工作原理
思路:先解释异步,再解释ajax如何使用
Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。
158、为什么扩展javascript内置对象不是好的做法?
因为扩展内置对象会影响整个程序中所使用到的该内置对象的原型属性
159、请解释一下javascript的同源策略
域名、协议、端口相同
160、什么是三元表达式?“三元”表示什么意思?
? :
因为运算符会涉及3个表达式
161、浏览器标准模式和怪异模式之间的区别是什么?
标准模式是指,浏览器按W3C标准解析执行代码;
怪异模式则是使用浏览器自己的方式解析执行代码,因为不同浏览器解析执行的方式不一样,所以我们称之为怪异模式。
浏览器解析时到底使用标准模式还是怪异模式,与你网页中的DTD声明直接相关,DTD声明定义了标准文档的类型(标准模式解析)文档类型,会使浏览器使用相应的方式加载网页并显示,忽略DTD声明,将使网页进入怪异模式
162、如果设计中使用了非标准的字体,你该如何去实现?
先通过font-face定义字体,再引用
@font-face
{
font-family: myFirstFont;
src: url(‘Sansation_Light.ttf’),
url(‘Sansation_Light.eot’); /* IE9+ */
}
163、用css分别实现某个div元素上下居中和左右居中
margin:0 auto;
164、module(12,5)//2 实现满足这个结果的modulo函数
function modulo(a,b){
return a%b;//return a/b;
}
165、HTTP协议中,GET和POST有什么区别?分别适用什么场景 ?
get传送的数据长度有限制,post没有
get通过url传递,在浏览器地址栏可见,post是在报文中传递
适用场景:
post一般用于表单提交
get一般用于简单的数据查询,严格要求不是那么高的场景
166、HTTP状态消息200 302 304 403 404 500分别表示什么
200:请求已成功,请求所希望的响应头或数据体将随此响应返回。
302:请求的资源临时从不同的 URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的
304:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。
403:服务器已经理解请求,但是拒绝执行它。
404:请求失败,请求所希望得到的资源未被在服务器上发现。
500:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源代码出现错误时出现。
167、HTTP协议中,header信息里面,怎么控制页面失效时间(last-modified,cache-control,Expires分别代表什么)
Last-Modified 文 档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档 才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
Expires 应该在什么时候认为文档已经过期,从而不再缓存它?
168、HTTP协议目前常用的有哪几个?KEEPALIVE从哪个版本开始出现的?
http1.0
http1.1 keeplive
169、业界常用的优化WEB页面加载速度的方法(可以分别从页面元素展现,请求连接,css,js,服务器等方面介绍)
170、列举常用的web页面开发,调试以及优化工具
sublime vscode webstorm hbuilder dw
httpwatch=>ie
ff:firebug
chrome:
171、解释什么是sql注入,xss漏洞
172、如何判断一个js变量是数组类型
ES5:Array.isArray()
[] instanceof Array
Object.prototype.toString.call([]);//"[object Array]"
173、请列举js数组类型中的常用方法
方法 描述
concat()
连接两个或更多的数组,并返回结果。
join()
把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop()
删除并返回数组的最后一个元素
push()
向数组的末尾添加一个或更多元素,并返回新的长度。
reverse()
颠倒数组中元素的顺序。
shift()
删除并返回数组的第一个元素
slice()
从某个已有的数组返回选定的元素
sort()
对数组的元素进行排序
splice()
删除元素,并向数组添加新元素。
toSource()
返回该对象的源代码。
toString()
把数组转换为字符串,并返回结果。
toLocaleString()
把数组转换为本地数组,并返回结果。
unshift()
向数组的开头添加一个或更多元素,并返回新的长度。
valueOf()
返回数组对象的原始值
174、FF与IE中如何阻止事件冒泡,如何获取事件对象,以及如何获取触发事件的元素
175、列举常用的js框架以及分别适用的领域
jquery:简化了js的一些操作,并且提供了一些非常好用的API
jquery ui、jquery-easyui:在jqeury的基础上提供了一些常用的组件 日期,下拉框,表格这些组件
require.js、sea.js(阿里的玉帛)+》模块化开发使用的
zepto:精简版的jquery,常用于手机web前端开发 提供了一些手机页面实用功能,touch
ext.js:跟jquery差不多,但是不开源,也没有jquery轻量
angular、knockoutjs、avalon(去哪儿前端总监):MV*框架,适合用于单页应用开发(SPA)
176、js中如何实现一个map
数组的map方法:
概述
map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。
语法
array.map(callback[, thisArg])
参数
callback
原数组中的元素经过该方法后返回一个新的元素。
currentValue
callback 的第一个参数,数组中当前被传递的元素。
index
callback 的第二个参数,数组中当前被传递的元素的索引。
array
callback 的第三个参数,调用 map 方法的数组。
thisArg
执行 callback 函数时 this 指向的对象。
实现:
Array.prototype.map2=function(callback){
for (var i = 0; i < this.length; i++) {
this[i]=callback(this[i]);
}
};
177、js可否实现面向对象编程,如果可以如何实现js对象的继承
创建对象的几种方式
实现继承的几种方式
原型链
178、约瑟夫环—已知n个人(以编号1,2,3…分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
179、有1到10w这个10w个数,去除2个并打乱次序,如何找出那两个数?
180、如何获取对象a拥有的所有属性(可枚举的、不可枚举的,不包括继承来的属性)
Object.keys——IE9+
或者使用for…in并过滤出继承的属性
for(o in obj){
if(obj.hasOwnproperty(o)){
//把o这个属性放入到一个数组中
}
}
181、有下面这样一段HTML结构,使用css实现这样的效果:
左边容器无论宽度如何变动,右边容器都能自适应填满父容器剩余的宽度。
182、下面这段代码想要循环昝输出结果01234,请问输出结果是否正确,如果不正确,请说明为什么,并修改循环内的代码使其输出正确结果 for(var i=0;i<5;++i){ setTimeout(function(){ console.log(i+’’); },100*i); } 183、解释下这个css选择器什么发生什么? [role=nav]>ul a:not([href^-mailto]){} 184、JavaScript以下哪条语句会产生运行错误 A. var obj = (); B. var obj = []; C. var obj = {}; D. var obj = //; 答案:AD 185、以下哪些是javascript的全局函数:(ABCDE) A. escape 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。ECMAScript v3 反对使用该方法,应用使用 decodeURI() 和 decodeURIComponent() 替代它。 B. parseFloat parseFloat() 函数可解析一个字符串,并返回一个浮点数。 该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。 C. eval 函数可计算某个字符串,并执行其中的的 JavaScript 代码。 D. setTimeout E. alert 186、关于IE的window对象表述正确的有:(CD) A. window.opener属性本身就是指向window对象 window.opener返回打开当前窗口的那个窗口的引用. 如果当前窗口是由另一个窗口打开的, window.opener保留了那个窗口的引用. 如果当前窗口不是由其他窗口打开的, 则该属性返回 null. B. window.reload()方法可以用来刷新当前页面 //正确答案:应该是location.reload或者window.location.reload C. window.location=”a.html”和window.location.href=”a.html”的作用都是把当前页面替换成a.html页面 D. 定义了全局变量g;可以用window.g的方式来存取该变量 187、描述错误的是 D A:Http状态码302表示暂时性转移 对 B:domContentLoaded事件早于onload事件 //正确 当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了。 当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。 C: IE678不支持事件捕获 D:localStorage 存储的数据在电脑重启后丢失 //错误,因为没有时间限制 try...catch 语句。(在 IE5+、Mozilla 1.0、和 Netscape 6 中可用) 188、关于link和@import的区别正确的是 A A: link属于XHTML标签,而@import是CSS提供的; B:页面被加载时,link会同时被加载,而后者引用的CSS会等到页面被加载完再加载 C:import只在IE5以上才能识别 而link是XHTML标签,无兼容问题 D: link方式的样式的权重高于@import的权重 189、下面正确的是 A A: 跨域问题能通过JsonP方案解决 B:不同子域名间仅能通过修改window.name解决跨域 //还可以通过script标签src jsonp C:只有在IE中可通过iframe嵌套跨域 //任何浏览器都可以使用iframe D:MediaQuery属性是进行视频格式检测的属性是做响应式的 188、错误的是:AC A: Ajax本质是XMLHttpRequest //异步请求json和xml数据 B: 块元素实际占用的宽度与它的width、border、padding属性有关,与background无关 C: position属性absolute、fixed、---relative---会使文档脱标 D: float属性left也会使div脱标 189、不用任何插件,如何实现一个tab栏切换? 通过改变不同层的css设置层的显示和隐藏 190、基本数据类型的专业术语以及单词拼写 191、变量的命名规范以及命名推荐 192、三种弹窗的单词以及三种弹窗的功能 alert confirm prompt 193、console.log( 8 | 1 ); 输出值是多少? 答案:9 194、只允许使用 + - * / 和 Math.* ,求一个函数 y = f(x, a, b);当x > 100 时返回 a 的值,否则返回 b 的值,不能使用 if else 等条件语句,也不能使用|,?:,数组。 答案: function f(x, a, b) { var temp = Math.ceil(Math.min(Math.max(x - 100, 0), 1)); return a * temp + b * (1 - temp); } console.log(f(-10, 1, 2)); 195、JavaScript alert(0.4*0.2);结果是多少?和你预期的一样吗?如果不一样该如何处理? 有误差,应该比准确结果偏大。 一般我会将小数变为整数来处理。当前之前遇到这个问题时也上网查询发现有人用try catch return写了一个函数, 当然原理也是一致先转为整数再计算。看起来挺麻烦的,我没用过。 196、一个div,有几种方式得到这个div的jQuery对象? 想直接获取这个div的dom对象,如何获取?dom对象如何转化为jQuery对象? var domView=document.getElementById(“nodesView”) document.getElementsByClassName(“aabbcc”); document.querySelector(“.aabbcc#nodesView”); 转换为jquery对象:
(
d
o
m
V
i
e
w
)
197
、
主
流
浏
览
器
内
核
I
E
t
r
i
d
e
n
t
火
狐
g
e
c
k
o
谷
歌
苹
果
w
e
b
k
i
t
O
p
e
r
a
:
P
r
e
s
t
o
198
、
如
何
显
示
/
隐
藏
一
个
d
o
m
元
素
?
请
用
原
生
的
J
a
v
a
S
c
r
i
p
t
方
法
实
现
d
o
m
.
s
t
y
l
e
.
d
i
s
p
l
a
y
=
”
n
o
n
e
”
;
d
o
m
.
s
t
y
l
e
.
d
i
s
p
l
a
y
=
”
”
;
199
、
J
a
v
a
S
c
r
i
p
t
有
哪
几
种
数
据
类
型
N
u
m
b
e
r
S
t
r
i
n
g
B
o
o
l
e
a
n
N
u
l
l
U
n
d
e
f
i
n
e
d
O
b
j
e
c
t
200
、
j
Q
u
e