百度某部门面试原题
本文适合最近在考虑新机会的的小伙伴阅读
欢迎关注前端早茶,与广东靓仔携手共同进阶~
作者:广东靓仔
一、背景
这套题目是广东靓仔认识的一位前端妹子经过“一番努力”Get到的,感谢~
二、原题
设置元素的backgroud 哪些区域颜色会改变
background填充区域默认为content、padding和border区域。
然而该行为由background-clip属性决定,默认为border-box该属性对应的
FOUC 无样式闪烁(文档样式短暂失效)@import
如果使用import方法对CSS进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁,这种现象称之为文档样式短暂失效(Flash of Unstyled Content),简称为FOUC。
当样式表晚于结构性html加载,当加载到此样式表时,页面将停止之前的渲染。此样式表被下载和解析后,将重新渲染页面,也就出现了短暂的花屏现象。
使用LINK标签将样式表放在文档HEAD中。
重绘重排区别
当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。比如改变某个元素的背景色、文字颜色、边框颜色等等
减少重排次数和缩小重排影响范围解决方式:
你们项目中Token是怎么拿到的
用户登陆,发送手机号码和验证码 后台接收参数,查找用户,用户存在就生成token,返回给前端 前端登陆成功,把token存到vuex(做持久化) 使用axios拦截器,读取vuex中的token,并放入请求头 请求其他接口,就会带上token 后台在需要登陆的接口上,获取token,解密token获得userId,返回前端需要的数据 用户在下次使用app,如果token还在有效期内,不需要重新登陆
有不同的或者更好的方案也可以回答,发散题,自由发挥
cookie是什么?
拓展说明,加分项:
时效性
httpOnly
Js数据类型有哪些
基本类型引用类型区别
基本类型的值是不可变得:
判断一个对象是不是数组
方法1:
根据对象的class属性来判断
let obj = []
console.log(Object.prototype.toString.call(obj) === '[object Array]')
方法2:
Array.isArray直接判断
let obj = []
console.log(Array.isArray(obj))
js数组遍历都有哪些方法
这里列举12种,具体如下所示:
1.for循环
for(i = 0,len=arr.length; i < len; i++) {
}
2.foreach循环
// 没有返回值,对原数组无影响
arr.forEach((item,index,array)=>{
//执行代码
})
// 参数:value数组中的当前项, index当前项的索引, array原始数组;
3.map循环
var ary = [12,23,24,42,1];
var res = ary.map(function (item,index,ary ) {
return item*10;
})
console.log(res);//-->[120,230,240,420,10]; 原数组拷贝了一份,并进行了修改
console.log(ary);//-->[12,23,24,42,1]; 原数组并未发生变化
4.forof遍历
for (var value of myArray) {
console.log(value);
}
5.filter遍历
var arr = [73,84,56, 22,100]
var newArr = arr.filter(item => item>80) //得到新数组 [84, 100]
console.log(newArr,arr)
6.every遍历
every()是对数组中的每一项运行给定函数,如果该函数对每一项返回true,则返回true。
var arr = [ 1, 2, 3, 4, 5, 6 ];
console.log( arr.every( function( item, index, array ){
return item > 3;
}));
// false
7.some遍历
var arr = [ 1, 2, 3, 4, 5, 6 ];
console.log( arr.some( function( item, index, array ){
return item > 3;
}));
// true
8.reduce
var total = [0,1,2,3,4].reduce((a, b)=>a + b); //10
reduce接受一个函数,函数有四个参数,分别是:上一次的值,当前值,当前值的索引,数组
[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});
9.reduceRight
reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加。
var arr = [0,1,2,3,4];
arr.reduceRight(function (preValue,curValue,index,array) {
return preValue + curValue;
}); // 10
10.find
var stu = [
{
name: '张三',
gender: '男',
age: 20
},
{
name: '王小毛',
gender: '男',
age: 20
},
{
name: '李四',
gender: '男',
age: 20
}
]
stu.find((element) => (element.name == '李四'))
//返回结果为
//{name: "李四", gender: "男", age: 20}
11.findIndex
对于数组中的每个元素,findIndex 方法都会调用一次回调函数(采用升序索引顺序),直到有元素返回 true。只要有一个元素返回 true,findIndex 立即返回该返回 true 的元素的索引值。如果数组中没有任何元素返回 true,则 findIndex 返回 -1。
findIndex 不会改变数组对象。
[1,2,3].findIndex(x => x == 4);
// Returns an index value of -1.
12.keys,values,entries
ES6 提供三个新的方法 —— entries(),keys()和values() —— 用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
Js事件循环机制
1. 一类是基于 Browsing Context ,
2. 一种是基于 Worker
二者是独立运行的。
任务队列
任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;
而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。
在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下:
在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次) 检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue 更新 render 主线程重复执行上述步骤
深浅拷⻉贝区别
仅拷贝对象的非对象属性(基本类型属性)、不可变对象属性,但是不拷贝对象的对象属性(不含不可变对象) ,即为浅拷贝。
以下这些函数得到的都是浅拷贝:
Object.assign、Array.prototype.slice()、Array.prototype.concat()
对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
简单理解:深拷贝会拷贝所有的属性。深拷贝前后两个对象互不影响。
JSON.parse(JSON.stringify())、手写递归函数、函数库lodash
箭头函数特点
Js垃圾回收方法
(1)标记清除法
Vuex更新流程
vuex的工作流程就是:
(1)通过dispatch去提交一个actions,
(2)actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,
(3)actions通过commit去触发mutations,
(4)mutations去更新state数据,state更新之后,就会通知vue进行渲染
拓展:
不能在mutations执行异步操作
Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。
vue keep-alive组件有什么用
用于保留组件状态或避免重新渲染(缓存的作用)
两个属性include与exclude
二者都可以用逗号分割字符串、正则表达式或者一个数组。
<keep-alive include="a,b">
<component :is="view">component>
keep-alive>
<keep-alive :include="/a|b/">
<component :is="view">component>
keep-alive>
<keep-alive :include="['a', 'b']">
<component :is="view">component>
keep-alive>
如何监听一个变量的变化 长度 index
defineProperty
var a = { watchValue:0 };
var lastTimeValue=a.watchValue;
Object.defineProperty(a, 'watchValue', {
get: function() {
console.log('get:' + watchValue);
return watchValue;
},
set: function(value) {
watchValue = value;
if(lastTimeValue!=watchValue){
lastTimeValue=watchValue;
console.log('value changed!! set: ' + watchValue);
}
}
});
proxy
var observe1 = (object, onChange) => {
const handler = {
get(target, property, receiver) {
try {
return new Proxy(target[property], handler);
} catch (err) {
return Reflect.get(target, property, receiver);
}
},
set(target, key, value, receiver) {
onChange(value);
return Reflect.set(target, key, value, receiver);
}
};
return new Proxy(object, handler);
};
var obj = {
foo: false,
a: {
x:{y: 4},
b:[{c: false}]
}
};
var watchedObj = observe1(obj,(val)=>{
console.log(`哈哈哈,监听到值变化为${val}了`);
});
watchedObj.foo = true;
watchedObj.a.x.y = 5; // 监听到值变化为5了
watchedObj.a.b[0].c = true;
webpack lorder / plugin
webpack是一个模块打包器(module bundler),提供了一个核心,核心提供了很多开箱即用的功能,同时它可以用loader和plugin来扩展。
loader的使用方式
1:在配置文件webpack.config.js中配置
module.exports = {
module: {
rules: [
{
test: /\.txt$/,
use: 'raw-loader'
}
]
}
}
2:通过命令行参数方式
webpack --module-bind 'txt=raw-loader'
3:通过内联使用
import txt from 'raw-loader!./file.txt';
webpack常用的loader
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use:[
{loader:'style-loader'},
{loader:'css-loader',options:{sourceMap:true,modules:true}},
{loader:'sass-loader',options:{sourceMap:true}}
],
exclude:/node_modules/
}
]
}
}
webpack常用的plugin
写一个webpack插件步骤如下:
1. 编写一个JavaScript命名函数。
2. 在它的原型上定义一个apply方法。
3. 指定挂载的webpack事件钩子。
4. 处理webpack内部实例的特定数据。
5. 功能完成后调用webpack提供的回调。
package.json package.lock.json 区别
package.json
Node.js 项目遵循模块化的架构,当我们创建了一个 Node.js 项目,意味着创建了一个模块,这个模块的描述文件,被称为 package.json。
属性说明:
name - 包名; version - 包的版本号; description - 包的描述; homepage - 包的官网URL; author - 包的作者,它的值是你在 https://npmjs.org 网站的有效账户名,遵循“账户名<邮件>”的规则,例如:zhangsan ; contributors - 包的其他贡献者; dependencies / devDependencies - 生产/开发环境依赖包列表。它们将会被安装在 node_module 目录下; repository - 包代码的 Repo 信息,包括 type 和 URL,type 可以是 git 或 svn,URL 则是包的 Repo 地址; main - main 字段指定了程序的主入口文件,这个字段的默认值是模块根目录下面的 index.js; keywords - 关键字
devDependencies、dependencies、peerDependencies的区别
package.lock.json
怎么转化less为css
Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护、方便制作主题、扩充。
webpack的配置如下:
module: {
rules: [{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"]
//编译方向从右到左less-loader=>css-loader=>style-loader
}, {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
}]
}
把样式文件less转为css并且单独提取出来(不放置在bundle.js中)
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
plugins: [
new ExtractTextPlugin('style.css')
//if you want to pass in options, you can do so:
//new ExtractTextPlugin({
// filename: 'style.css'
//})
]
}
地址栏输入一个url到页面渲染过程
1、HTTP 请求准备阶段
构建请求--浏览器构建请求行信息,准备发起网络请求 GET /index.html HTTP1.1 查找缓存--如果浏览器发现请问资源在浏览器中存在副本,根据强缓存规则,如没有过期那么直接返回资源,如何查找失败进入下一个环节:
--准备 ip 地址和端口
--DNS(域名和ip的映射系统) 域名解析,拿到ip之后找端口,默认为80
--建立tcp链接(三次握手)
--如果是https 还需要建立TLS连接
2、HTTP 发送请求
3、HTTP 响应返回
浏览器拿到响应数据,首先判断是否是4XX或者5XX是就报错,如果是3XX就重定向,2XX就开始解析文件,如果是gzip就解压文件 TCP断开连接 4次挥手
浏览器解析渲染
建立根据html建立dom树和css树,如果遇到script首选判断是否defer和async否则会阻塞渲染并编译执行js,如果没有则组合生成render tree,最后浏览器开启GPU进行绘制合成图层,将内容显示屏幕。
content-type作用
Content-Type 实体头部用于指示资源的MIME类型 media type 。
在请求中 (如POST 或 PUT),客户端告诉服务器实际发送的数据类型。
Content-Type 的值类型:
1.1 application/json:消息主体是序列化后的 JSON 字符串
1.2 application/x-www-form-urlencoded:数据被编码为名称/值对。这是标准的编码格式
1.3 multipart/form-data: 需要在表单中进行文件上传时,就需要使用该格式。常见的媒体格式是上传文件之时使用的
1.4 text/plain:数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符
介绍知道的状态码,状态码301、302区别
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
HTTP状态码301与302的区别:
1、它们之间关键区别在,资源是否存在有效性;
2、301资源还在只是换了一个位置,返回的是新位置的内容;
3、302资源暂时失效,返回的是一个临时的代替页上。
sessionstorage localstorage区别
1.生命周期
localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。
sessionStorage的生命周期是仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。
2.存储大小
3.存储位置
localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信
4.存储内容类型
localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理
5.获取方式
localStorage:window.localStorage
sessionStorage:window.sessionStorage
6.应用场景
localStorage:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据
sessionStorage:敏感账号一次性登录
浏览器为啥第二次访问就快了
主要原因是这些网站把很多资源都缓存在了本地,浏览器缓存直接使用本地副本来回应请求,而不会产生真实的网络请求,从而节省了时间。同时,DNS 数据也被浏览器缓存了,这又省去了 DNS 查询环节。
DNS 缓存和页面资源缓存这两块数据是会被浏览器缓存的。
1)、DNS 缓存比较简单,它主要就是在浏览器本地把对应的 IP 和域名关联起来。
2)、重点看下浏览器资源缓存,下面是缓存处理的过程:
怎么减少页面加载时间
1、压缩css、js文件
2、合并js、css文件,减少http请求
3、外部js、css文件放在最底下
4、减少dom操作,尽可能用变量替代不必要的dom操作
5、优化图像(格式选择、懒加载等等)
6、使用CDN
7、使用缓存
8、减少 http 请求(合并文件,合并图片)
9、标明高度和宽度
10、网址后加斜杠
11、优化TCP协议
遇到的棘手的问题,完成了什么工作
开放性题目,自由作答。
三、最后
关注我,一起携手进阶
欢迎关注前端早茶,与广东靓仔携手共同进阶~