CSS 面试题
一、css选择器的优先级排序和权重
1、!important >行内样式【权重:1000】>id选择器【权重:100】>class选择器、属性选择器[type="text"]【权重:10】>标签选择器【权重:1】>子选择器、相邻选择器、通配符选择器(*)【权重:0】>浏览器自定义属性和继承.【没有权重】。
注意:css选择器有一个权重,如果权重越大优先级越高。
*二、css元素水平垂直居中
1、利用父元素text-align:center 与margin:auto;
2、用定位居中元素:有兼容性问题
3、利用弹性布局水平垂直居中
注意:定位与弹性布局有兼容性问题。(水平垂直方法有很多,根据情况而定)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素水平垂直居中</title>
</head>
<style>
/* 第一种 */
.element_center {
text-align: center;
margin:auto
}
.item_element{
display: inline-block;
border:1px solid red;
/* 配合第一种方法*/
margin:50% 0;
}
/* 第二种利用定位 */
/* .element_center {
position: fixed;
left: 50%;
top: 50%;
transform:translateX(-50%);
} */
/* 第三种利用弹性布局 */
/* .element_center{
display: flex;
justify-content: center;
align-items: center;
height: 500px;
border:1px solid red;
} */
</style>
<body>
<div class="element_center">
<div class="item_element">
居中元素
</div>
</div>
</body>
</html>
<script>
</script>
</html>
三、CSS 中的 BFC:详解:10 分钟理解 BFC 原理 - 知乎
BFC:英文(block firmatting contexts) 格式化上下文 ,具有 BFC 特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。
BFC功能总结
1、可以利用BFC解决两个相邻元素的上下margin重叠问题;
2、可以利用BFC解决高度塌陷问题;
3、可以利用BFC实现多栏布局(两栏、三栏、圣杯、双飞翼等)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
/* 第一种特性 解决外边距重叠问题 */
.div {
overflow: visible;
border: 20px solid red;
}
p {
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
/* 第二种特性 BFC计算元素高度时子元素如果是浮动时父元素边距也会参与计算 */
/* float: left; */
}
/* 第三种特性:overflow: hidden; 浮动时解决父元素高度塌陷问题 */
.outside {
border: 10px solid blue;
overflow: hidden;
}
.inside {
width: 200px;
height: 200px;
background: yellowgreen;
float: left;
border-left:20px solid red;
}
/* 第四种特性:BFC的区域不会与浮动容器发生重叠 */
.left{
width:100px;
height:100px;
background: yellow;
float: left;
}
.right{
height:300px;
background:blue;
/* 通过overflow:hidden解决浮动重叠问题 */
overflow: hidden;
}
</style>
<body>
<h1> 第一种特性: 解决外边距重叠问题</h1>
<h1> 第二种特性:BFC计算元素高度时子元素如果是浮动时父元素边距也会参与计算</h1>
<div class="div">
<p></p>
</div>
<div class="div">
<p></p>
</div>
<h1>第种特性:overflow: hidden; 浮动时解决父元素高度塌陷问题</h1>
<div class="outside">
<div class="inside"></div>
</div>
<h1>第四种特性:BFC的区域不会与浮动容器发生重叠(通过overflow:hidden解决浮动重叠问题)</h1>
<div class="left"></div>
<div class="right"></div>
</body>
</html>
四、弹性布局:父元素display:flex,子元素:flex:1
flex:1 是由flex-grow、flex-shrink、flex-basis三个属性的缩写。
flex-grow: 默认为0 , 1:等分剩余空间。 => 定义项目的的放大比例;
flex-shrink: 默认为1、0 空间不足时,缩小的比例相同 。 =>定义项目的缩小比例
flex-basis:默认值为auto,设置后项目将占据固定空间。 => 定义在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据此属性计算主轴是否有多余空间,
<!DOCTYPE html>
<html lang="en">
<style>
.div1{
display: flex;
width: 100%;
border:1px solid yellow;
height:100px;
}
.div2,.div3,.div4{
background-color:red;
flex-grow:2;
}
.div3{
background-color:blue;
/*
flex-grow:1 //它指定了flex容器中剩余空间的多少应该分配给项目(flex增长系数);
flex-shrink:1 //定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小;
flex-basis:auto //指定了 flex 元素在主轴方向上的初始大小(给上面两个分配多余空间之前,计算项目是否有多余空间,默认值为auto,即项目本身大小);
详情:https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex
*/
flex:2
}
.div4{
background-color: purple;
flex:1
}
</style>
<body>
<div class="div1">
<div class="div2">div2</div>
<div class="div3">div3</div>
<div class="div4">div4</div>
</div>
</body>
</html>
JavaScript面试题
一、ES6都有那些新特性
1、块级作用域let、const;
2、变量的解构赋值;
3、箭头函数
4、参数处理
1、默认参数,2、剩余参数,
5、Promise
6、Set和Map数据结构
7、Proxy
8、class 基本语法
class Point{
constructor(x,y){
this.x = x;
this.y = y;
}
toString(){
return `${this.x}+${this.y}`
}
}
一、声明变量 var 、let 、const 区别
var:声明变量提升。
let:块级作用域,同一个作用域不能重复定义,没有变量提升。
const:不存在变量得升,如果定义是一个基本数据类型一旦定义不能改变,如果是一个引用数量类型可以赋值给引用数据类型。
const one = {a:'c'}
let two= 'cc'
//报错:不能赋值给常量
// one = two;
//正确
one.a = two //{a:cc}
二、深浅拷贝 :详解:JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑 - 古兰精 - 博客园
- 浅拷贝:只是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据
- 深拷贝:将数据中所有的数据拷贝下来,对拷贝之后的数据进行修改不会影响到原数据。
1、JSON.parse(),JSON.stringfiy() 注意:有数据结构限制,必须是JSON数据结构,如果有函数、undefined会丢失,如果数据里有NaN、infinity 和-Infinity ,刚序列化的结果会变成null
2、concat() , slice() 只能深拷贝单层数据结构
3、Object.assign({}, a):当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在一级属性以后就是浅拷贝。
4、使用递归的方式实现深拷贝
function _deepClone(source) {
let target;
if (typeof source === 'object') {
target = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] !== 'object') {
target[key] = source[key]
} else {
target[key] = _deepClone(source[key])
}
}
}
} else {
target = source
}
return target
}
三、原型和原型链
1、在声明了一个函数之后,浏览器会自动按照一定的规则创建一个对象,这个对象就叫做原型对象。这个原型对象其实是储存在了内存当中。
2:原型链:每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
闭包:
在一个函数中包含另一个函数。保护函数内部声明的变量是局部的,只能在函数内部访问到,让函数内部变量一直保持在内存中,不被垃圾回收机制处理。
在IE浏览器会造成内存泄露,其它浏览器要合理运用,用完请手动施放。
4.、为什么会跨域
跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号相同,则允许相互访问,JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等
4.1、解决跨域问题都有那些方法:详解:视频去哪了呢?_哔哩哔哩_bilibili
- jsonp:
- cors
- postMessage
- document.domain:有域名限制只能是一级域名和二级域名
- window.name
- location.hast
- http-proxy
- nginx
- websockey
五、判断一个对象是否为数组
var arr = [1,2,23]
// 判断一个对象是否为数组有几种方法
/*
1、判断构造函数 instanceof
*/
console.log('arr instanceof Array',arr instanceof Array)
/*
2、判断原型对像
*/
console.log('Array.prototype.isPrototypeOf(arr)',Array.prototype.isPrototypeOf(arr))
/*
3、判断隐藏的class属性
class属性: 隐藏在每个对象内部,记录对象创建时的类型名。不随继承关系改变而改变。
问题: class属性是内部隐藏属性,不能用.直接访问!
解决: 只有顶级父类型Object.prototype中的toString()才可输出class属性值
问题: 内置类型的prototype中都重写了新的toString()覆盖了顶级的toString()
*/
console.log('Object.prototype.toString.call(arr)',Object.prototype.toString.call(arr) == '[object Array]')
/*
4、es5新增的api isArray()
*/
console.log('Array.isArray(arr)',Array.isArray(arr))
this的指向
六、改变this指向问题
call()--不需要,传参就指向,参数只能一个一个传
apply()---参数为数组
bind()--需要调用
七、Promise promise经典面试题 - 前端小赤佬 - 博客园
Promise有三种状态,等待、成功、失败,被标记为完成不会再次改变状态。
resolve
函数和reject
函数都将当前Promise
状态改为完成,并将异步结果,或者错误结果当做参数返回。
八、如何中断ajax请求
1、停止javascript的ajax请求,一种是设置超时时间让ajax自动断开,另一种为手动去停止ajax请求,其核心是调用XMLHttpRequest对象上的abort方
var ajax = $.ajax({
"error":function(jqXHR,textStatus,errorThrown){
if(errorThrown != 'abort'){
alert('您的ajax方法被停止')
}
}
})
ajax.abort()//停止ajax
注意:不要用abort方法来作为终止对服务器的请示操作,只能当作在前端页面立即停止执行ajax成功后的方法,执行abort方法后ajax可能对服务器发送了请示,只是还未返回信息。
九、防抖、节流
1、为了节约js事件的重复调用与服务器开销而做的优化。
防抖,节流的插件:GitHub - mr-xiao-han/jiuaiDebounce: 防重复提交,防抖函数,节流
Vue面试题
一、vuex存储与本地储存(localstorage、sessionstorage)的区别
1、区别:vuex存储在内存,localstorage(本地存储)则以文件的方式存储在本地,永久保存,sessionstorage( 会话存储 ) ,临时保存;
2 、应用场景:vuex用于组件之间的传值,localstorage,sessionstorage则主要用于不同页面之间的传值。
3、永久性:当刷新页面(这里的刷新页面指的是 --> F5刷新,属于清除内存了)时vuex存储的值会丢失,sessionstorage页面关闭后就清除掉了,localstorage不会。
二、vue中watch和computed的区别
1、computed是计算属性,名称不能与 data 里对象重复,有缓存性,只能用同步,必须有 return; 是多个值变化引起一个值变化,是多对一.
2、watch:是一个函数,名称必须和 data 里对象一样,可以用于异步,没有 return;是一对多,监听一个值,一个值变化引起多个值变化。
三、vue 都有那些传值方法
1、props / $emit
适用 父子组件通信
2、ref
与 $parent / $children
适用 父子组件通信
ref
:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,
$parent / $children
:访问父 / 子实例
3、EventBus ($emit / $on)
适用于 父子、隔代、兄弟组件通信
4、$attrs/$listeners
适用于 隔代组件通信
$attrs
:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 ( class 和 style 除外 )。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过v-bind="$attrs"
传入内部组件。通常配合 inheritAttrs 选项一起使用。$listeners
:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过v-on="$listeners"
传入内部组件
5、provide / inject
适用于 隔代组件通信
6、Vuex
适用于 父子、隔代、兄弟组件通信
三、vue双向绑定的原理:
vue2.x数据双向绑定是通过Object.defineProperty()数据劫持结合发布者-订阅者模式的方式来实现的,
vue3.x数据双向绑定是通过Proxy
四、vue中key的作用:
vue中的 key 是为了vue中 虚拟节点的唯一标记,通过这个key,可以更加的准确,快速。提高性能。
五、Vuex :
state:驱动应用的数据源;
Getters:从基本数据派生的数据,允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性;
Mutation:更改store中状态的唯一方法,必须是同步函数
Actions:包裹mutations,使之可以异步。用于提交 mutation,而不是直接变更状态,可以包含任意异步操作;
Modules:分割模块,让每一个模块拥有自己的state、mutation、action、getter
1、vuex怎么触发多个action:Action 通过 store.dispatch
方法触发
//第一中方法利用 async / await
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}
六、vue单向数据流:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
七、直接给一个数组项赋值,Vue 能检测到变化吗?
由于 JavaScript 的限制,Vue 不能检测到以下数组的变动:
1、当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
解方法:
vm.$set(vm.items, indexOfItem, newValue)
2、当你修改数组的长度时,例如:vm.items.length = newLength
解决方法:
vm.items.splice(newLength)
vue路由守卫:vue-router钩子函数实现路由守卫 - 有梦想的咸鱼前端 - 博客园
vue-router一共给我们提供了三大类钩子函数来实现路由守卫:
1、全局钩子函数(beforeEach、afterEach)
2、路由独享的钩子函数(beforeEnter)
3、组件内钩子函数(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)
beforeEach一共接收三个参数,分别是to、from、next;to:即将进入的路由对象;from:正要离开的路由对象;next:路由的控制参数;
next一共有四种调用方式:
next():一切正常调用这个方法进入下一个钩子;
next(false):取消路由导航,这时的url显示的是正要离开的路由地址;
next('/login'):当前路由被终止,进入一个新的路由导航(路由地址可以自由指定)
next(error):路由导航终止并且错误会被传递到router.onError()注册过的回调中;
AfterEach:
AfterEach和beforeEach一样都是属于全局守卫钩子,都是在main.js中进行调用;其中AfterEach比beforeEach少一个next参数;
to:即将要进入的路由对象;
from:正要离开的路由对象;
afterEach()我们一般用来重置页面滚动条位置:
假如我们有一个页面很长,滚动后其中的某个位置后跳转,这时新的页面的滚动条位置就会在上一个页面停留的位置;这个时候我们就可以利用afterEach进行重置:
Http面试题:
一、简单说下Http的请求过程
1、浏览器根据域名解析IP地址
2、浏览器与WEB服务器通过三次握手建立一个TCP连接
3、浏览器会给WEB服务器发送一个Http请求
4、服务器端响应HTTP请求,浏览器得到HTML代码
5、浏览器解析html代码,并请求html代码中的资源。
6、把请求到的资源与HTML代码进行渲染呈现给用户,并关闭TCP连接。
二、重绘,回流
回流:当元素的规模尺寸,布局,隐藏等改变面需要重新构建这就称为回流,每个页面至少需要一次回流,在回流时浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制爱影响的部分到屏幕中,这个过程成为重绘。
重绘:当render tree中的一些元素需要更新属性,而这些属性只影响元素外观,风格而不会影响布局,就叫重绘。比如改变背景色,
区别:回流必将引起重绘,但重绘不一定会引起回流。
三、https和http的区别
http是超文本传输协议,是无状态的,传输的数据是明文,默认端口80
https协议是http协议加ssl构建的可进行加密传输,认证的网络协议,防止数据在传输过程中不被窃取,改变,确保数据的完整性,默认端口443。
性能优化
一、静态资源文件缓存:解决静态资源文件js/css缓存问题(超详细总结版)_a624193873的博客-CSDN博客
第一种方法:在html文件加入缓存
<meta http-equiv="Cache-Control" content="max-age=7200" />
这句话的作用是修改服务器的响应该html文件的响应头,设置其中静态资源文件的缓存时间为7200秒,但是浏览器设置有时不生效,主要原因是因为页面优先级是最低的。
第二种方法:springboot配置,服务端配置
服务端修改响应头和设置版本号两部分,过版本号来区分自己缓存的js与css文件是否为最新的版本。
第三种方法:修改nginx配置文件
nginx的优先级更高,nginx是一个实现反向代理和负载均衡的轻量级web服务器,许多项目都会使用到它来做代理。可以理解为它是所有web服务器的统一入口和出口,也就是说我们所有的数据都是从springboot中集成的web服务器出来后,再由nginx代理,作处理后响应给浏览器。nginx最后对响应头作处理,所以会对之前的所有处理进行覆盖。
location ~* \.(woff)$ {
proxy_pass http://kubernetes;
expires 1d;
}
二、图片如何进行懒加载
1、加载loading图片
2、判断哪些图片要懒加载
3、隐形加载图片(请求真图片地址)
4、替换掉真图片