初级前端面试题整理

159 阅读7分钟

没有顺序,都是这次找工作中确实遇到的问题

一. 盒子水平垂直居中

经常遇到(只要能说出弹性布局的,基本就可以了)

<body>
    <div></div>
</body>
  1. display:flex
 html,body {
        display: flex;
        height: 100%;
        justify-content: center;
        align-items: center;
     }

     div {
         box-sizing: border-box;
         width: 100px;
         height: 50px;
         background: pink;
     }
  1. 绝对定位 (要设置宽和高)
 html,body {
         height: 100%;
         overflow: hidden;
         position: relative;
     }
     div {
         box-sizing: border-box;
         position: absolute;
         width: 100px;
         height: 50px;
         background: pink;
         left: 0;
         top: 0;
         bottom: 0;
         right: 0;
         margin: auto;
     }
  1. 绝对定位(可以不设置宽高,兼容不好)
   html,body {
          height: 100%;
          overflow: hidden;
          position: relative;
      }
      div {
          box-sizing: border-box;
          position: absolute;
          background: pink;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
      }
  1. js (父盒子宽高-子宽高)/2
 html,body {
        height: 100%;
        position: relative;
     }

     div {
         box-sizing: border-box;
         width: 100px;
         height: 50px;
         background: pink;
     }
<script>
     let fu = document.documentElement;
     let winW = fu.clientWidth;
     let winH = fu.clientHeight;
     let zi = document.querySelectorAll("div")[0];
     let sonW = zi.offsetWidth;
     let sonH = zi.offsetHeight;
     zi.style.position="absolute"
     zi.style.left=(winW-sonW)/2 +'px'
     zi.style.top=(winH-sonH)/2 +'px'
 </script>
  1. 块内变行内 (父元素要有固定宽高)
html,body {
        width: 900px;
        height: 800px;
        display: table-cell;
        vertical-align: middle;
        text-align: center;
     }

     div {
         box-sizing: border-box;
         width: 100px;
         height: 50px;
         background: pink;
         display: inline-block;
     }

二. 盒模型

我基本没遇到过这种问题,但听说出的概率挺高

盒模型分为标准盒模型和IE模型(怪异盒模型),包括flex弹性布局,column多列布局 不同:

  • 盒模型的宽高只是内容(content)的宽高;
  • IE盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高
  • column多用于文章

三.经典布局

  • 圣杯布局
  • 双飞翼布局 =>(左右固定中间自适应)
<style>
      .container{
          height: 100%;
          padding: 0 200px;
      }
      .left,
      .right{
          width: 200px;
          min-height: 200px;
          background: lightskyblue;
          float: left;
      }
      .center{
          width: 100%;
          min-height: 400px;
          background: lightpink;
          float: left;
      }
      .left{
          margin-left: -100%;
          position: relative;
          left: -200px;
      }
      .right{
          margin-right: -200px;
      }
  </style>
<body>
  <div class="container clearfix">
      <div class="center"></div>
      <div class="left"></div>
      <div class="right"></div>
  </div>
</body>
     .container {
          width: 100%;
          float: left;
      }
      .left,
      .right {
          width: 200px;
          min-height: 200px;
          background: lightskyblue;
          float: left;
      }
      .container .center {
          margin: 0 200px;
          min-height: 400px;
          background: lightpink;
      }
      .left {
          margin-left: -100%;
      }
      .right {
          margin-left: -200px;
      }

  <div class="container">
      <div class="center"></div>
  </div>
  <div class="left"></div>
  <div class="right"></div>
     .container {
          width: 100%;
      }

      .left,
      .right {
          width: 200px;
          min-height: 200px;
          background: lightskyblue;
          float: left;
      }

      .container .center {
          width: calc(100% - 400px);
          min-height: 400px;
          background: lightpink;
          float: left;
      }
<div class="container">
      <div class="left"></div>
      <div class="center"></div>
      <div class="right"></div>
  </div>
      .container {
          display: flex;
          justify-content: space-between;
          height: 100%;
      }

      .left,
      .right {
          flex: 0 0 200px;
          min-height: 200px;
          background: lightskyblue;
      }

      .center {
          flex: 1;
          min-height: 400px;
          background: lightpink;
      }
      
  <div class="container">
      <div class="left"></div>
      <div class="center"></div>
      <div class="right"></div>
  </div>
      .container {
          position: relative;
          height: 100%;
      }

      .left,
      .right {
          position: absolute;
          top: 0;
          width: 200px;
          min-height: 200px;
          background: lightskyblue;
      }
      .right {
          right: 0;
      }
  
      .center {
          margin: 0 200px;
          min-height: 400px;
          background: lightpink;
      }
    <div class="container">
      <div class="left"></div>
      <div class="center"></div>
      <div class="right"></div>
  </div>

四. 移动端响应式布局

面试的时候遇到好几个问element-ui的布局原理,其实就是问响应式布局(媒体查询+rem+flex)

  • media
  • rem
  • flex
  • vh vw

五.怎么让1rem = 100px

当你回答完第四个问题后,面试官可能你这个问题,就看你是不是真的了解rem和屏幕适配

1.就是获取当前视口的宽

2.然后确定基准(最好直接是设计稿750px)宽

3.把基准分为100份,即750视口的宽度下font-size = 100px,1rem = 100px

4.然后当前视口的宽/7.5 + 'px'

var kk=document.documentElement.clientWidth;
  if(kk>750){
  	kk=750
  }
document.documentElement.style.fontSize=kk/7.5+"px"

六. url输入到网页到加载完会发生什么

  1. 浏览器的地址栏输入URL并按下回车。
  2. 浏览器查找当前URL的DNS缓存记录。
  3. DNS解析URL对应的IP。
  4. 根据IP建立TCP连接(三次握手)。
  5. HTTP发起请求。
  6. 服务器处理请求,浏览器接收HTTP响应。
  7. 渲染页面,构建DOM树。
  8. 关闭TCP连接(四次挥手)。

七. Tcp三次握手和四次挥手

当第六个问题回答完后,可能面试官就会问你三次握手和四次挥手了。我当时遇到的是笔试题目,不知道怎么描述就直接画图了,居然过了。

下方图片来自baijiahao.baidu.com/s?id=165422…

image.png

image.png

八.TCP与UDP区别,HTTP与HTTPS区别

UDP:无连接,不可靠,支持一对一,一对多,多对一和多对多交互通信,面向报文 TCP:面向报文,可靠,只能是一对一通信,面向字节流

九.为啥出现跨域问题

a页面想获取b页面资源时,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题限制了跨域访问,不允许跨域请求资源。

十.怎么解决跨域问题

1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

十一.get请求和post请求区别

1.get请求参数通过url传递,post请求放在request body中传递;
2.get请求产生一个TCP数据包;post请求产生两个TCP数据包;
3.post请求更安全,请求发送的数据更大;

十二.说出四个vue指令

  • v-if
  • v-show
  • v-model
  • v-bind
  • v-for
  • v-html
  • v-text

十三.v-if和v-show

  • v-if是通过控制dom节点的存在与否来控制元素的显隐;
  • v-show是通过设置DOM元素的display样式,block为显示,none为隐藏; 如果需要非常频繁地切换,使用 v-show;如果在运行时条件很少改变,用 v-if。

十四.vue渲染原理

将标签通过服务器生成html字符串,再发送到浏览器。更利于SEO和首屏渲染

十五.v-if和v-for

当v-if和v-for同时出现时,渲染函数会先执行到v-for。同时出现时会带来性能方面的浪费,可以将v-if提到外层。

十六.vue路由传参

1.页面刷新数据不会丢失

//子路由配置
{
path: '/child/:id',
component: Child
}
//父路由组件
<router-link :to="/child/123">进入Child路由</router-link>

2.页面刷新数据会丢失

this.$router.push(name:"url",params:{id:1})
this.$route.params.id

3.页面刷新数据不会丢失

this.$router.push(path:"url",query:{id:1})
this.$route.query.id

十七.vue子组件向父组件传值的方法

  1. 子组件通过通过this.$emit()的方式将值传递给父组件;\
  2. 通过vuex来传递组件间的数据;\
  3. 通过中央总线EventBus来传递组件间的数据;\
  4. 通过修改父组件传过来的对象属性\
  5. 父组件使用子组件的引用ref调用子组件的方法获取子组件的数据

十八.Vue 中常见的生命周期钩子函数。

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

十九.数组有哪些方法

  • toString(),转换成字符串
  • join(),将数组元素转换为字符串,通过指定的分隔符分隔
  • pop(),在数组末尾删除元素
  • push(),在数组末尾插入元素
  • shift(),删除数组的头部元素
  • unshift(),在数组的头部插入元素
  • splice(),在数组中添加删除或替换元素
  • concat(),数组和数组(或元素)的合并
  • slice(),提取字符串的某个部分
  • sort(),升序排序
  • reverse(),倒叙排序

二十.foreach和map区别

  • foreach会改变原数组,
  • map返回新数组,不会改变原数组

二十二.js数据类型

  • 基本类型: String、Number、boolean、null、undefined、bigInt
  • 引用类型:里面包含的 function、Array、Date。

二十三.css画一个三角

例:向下的三角

width:0px;
height:0px;
border-top:50px solid red;
border-left:50px solid transparent;
border-right:50px solid transparent;

二十四.let var const 区别

  • var 可以变量提升
  • let和const不能变量提升,有暂时性死区
  • const定义的变量不可以修改,而且必须初始化

二十五.怎么实现一个异步请求

1.async/await

async function action(){
  let result = await doSomething();
}
function doSomething(){...}

2.Promise

function doSomething(){
  return new Promise(function(resolve){
    ....
  });
 
} 
doSomething().then(result=>{
  ...
});

二十六.简述闭包

  • 闭包是指有权访问另一个函数作用域中的变量的函数
  • 闭包的作用就是可以在内存中保留一些变量,使其不被销毁

二十七.说出$router.push()$router.replace()区别

  • router.replace() 跳转路由,不会留下history记录
  • router.push()切换路由,但本质是在添加一个history记录

二十八.网页渲染过程

1.将HTML文本解释成DOM树(文档对象模型)。
2.将CSS解释成CSSOM树,形成CSS对象模型。
3.将CSSOM与DOM合并,构建渲染树。
4.布局和绘制。

二十九.冒泡排序

遇到很多次

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

三十.数组去重

方法很多列举两个。 注意,你要是用的递归,面试官会问你会不会用es6,你要是用es6,面试官就问你会不会原生递归

[...new Set(arr)] 
function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
return arr;
}

三十一.拍平数组

方法也很多列举两个。

function fn(arr){
    return arr.reduce((prev,cur)=>{
        return prev.concat(Array.isArray(cur)?fn(cur):cur)
    },[])
}
arr.flat(Infinity)

三十二.算法 获取 url 参数

输入:http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehekey
输出:[1, 2, 3]

一般来说算法题注重是思路,笔试写的烂没事,到时候把思路说给面试官听就好了,一般面试官不会真的去看你纸上的算法题的

function getUrlParam(sUrl, sKey) {

var paramArr = sUrl.split('?')[1].split('#')[0].split('&'); // 取出每个参数的键值对放入数组

const obj = {};

paramArr.forEach(element => {

const [key, value] = element.split('=');  // 取出数组中每一项的键与值`

if(obj[key] === void 0){   // 表示第一次遍历这个元素,直接添加到对象上面`

obj[key]=value

} else{

obj[key]=[].concat(obj[key],value); // 表示不是第一次遍历说明这个键已有,通过数组存起来。

}});

return sKey===void 0? obj:obj[sKey]||''   // 如果该方法为一个参数,则返回对象。

//如果为两个参数,sKey存在,则返回值或数组,否则返回空字符。

}

三十三.数组合并

var a = [1,2]
var b = [3,4]
a.push(...b)
var a = [1,2]
var b = [3,4]
var c = [...a,...b]
var a = [1,2]
var b = [3,4]
a.concat(b)

三十四.算法 柯里化

这个题我当时没做出来,柯里化

输入: var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
输出: 6
function curryIt(fn) {
    let args = []   

    return function curried(arg) {
        args.push(arg)       
        if (args.length >= fn.length) {
            return fn.apply(this, args)
        } else {
            return function(arg2) {   
                return curried.call(this, arg2)
            }
        }
    }
}