前端面试编程题

132 阅读3分钟

其实说到底是面试,实际上也是对基础知识的巩固。

tt一面

写一个两列固定,一列不固定的布局

<style type="text/css">
    .container {
        display: flex;
    }
    .left, .right {
        width: 200px;
    }
    .center {
        flex:1
    }
</style>
<div class="container">
        <div class="left">1</div>
        <div class="center"></div>
        <div class="right">3</div>
</div>

继续问: 如果center中有个子元素是200px,则会发生什么?

<style type="text/css">
    .container {
        display: flex;
        width: 500px;
    }
    .left, .right, .son {
        width: 200px;
    }
    .center {
        flex:1
    }
</style>
<div class="container">
        <div class="left">1</div>
        <div class="center">
            <div class="son">son</son>
        </div>
        <div class="right">3</div>
</div>

结果,中间元素由于flex:1,则会被子元素的200撑开;两侧分别为150px;

请实现如下的函数,可以批量请求数据,所有的URL地址在urls参数中,同时可以通过max参数 控制请求的并发度。当所有的请求结束后,需要执行callback回调。发请求的函数可以直接使用fetch

function requestMaxFun (urls, max, callback) {
    let i = 0, // 记录请求个数指针
    fetchArr = [];// 存储promise数组
    function toFetch() {
        if (i === urls.length) { // 当所有请求push完毕,应该立即停止,并返回promise对象,以供剩余请求进行
            console.log('所有请求结束')
            return Promise.resolve('push over');
        }
        let req = testFetch(urls[i++]); // 开始发送请求,并且i数量+1,因为下一次需要
        fetchArr.push(req); // 存储发送请求的实例
        req.then(() => { fetchArr.splice(fetchArr.indexOf(req), 1)}); // 当发送完一个请求,就把该请求从promise数组中删除(好比公交车下了一个人)

        let p = Promise.resolve(); // 实例化一个promise对象
        if (fetchArr.length >= max) {
                p = Promise.race(fetchArr); // 如果达到并发数,用race比较第一个完成的(公交车下了一个人)
        }
        return p.then(() => toFetch()) // 有一个完成的就再调用下一个
    }

    toFetch().then((val) => {
        return Promise.all(fetchArr) // 执行剩余的请求
    }).then((val) => {
        callback(); // 执行callback
    })
}
// 为了方便查看效果,手写一个模拟的fetch方法
function testFetch(i) {
    return new Promise((resolve, reject) => {
            setTimeout(() => {
                    console.log('send', i)
                    resolve(i)
            }, 10000 * Math.random());
    })
}
// 运行
requestMaxFun([1,2,3,4,5,6,7], 4, () => {console.log('over')})

二叉树所有根到叶子路径组成的数字之和


           1
     2           3 
 4      5

从根到叶子共3条:1->2->4, 1->2->5, 1->3

构成的数字为12412513,求和124 + 125 + 13 = 262即为所求
先构造js二叉树
// 测试数据如下:
let root = {
    val: 1,
    left: {
        val: 2,
        left: null,
        right: null,
    },
    right: {
        val: 3,
        left: null,
        right: null,
    }
}
// 124 125 13求和 = 262
function travalTreeSum(root) {
    if(!root) {
        return 0;
    }
    let sums = 0;
    getSum(root,0);
    function getSum(node, sum) {
            sum = sum * 10 + node.val; // 进十很重要
            if (node.left) {
                    getSum(node.left, sum)
            }
            if(node.right) {
                    getSum(node.right, sum)
            }
            if (!node.left && !node.right) { // 计算和的时机是没有子节点
                    sums += sum;
            }
    }
    return sums;
}
// 调用
travalTreeSum(root);

递归怎么优化呢?

  1. 尾递归:只会占用衡量的内存,在函数返回的时候,调用自身本身,并且return语句不能包含表达式

参考文章www.cnblogs.com/wjyz/p/1054…

终结!

一面

  1. Dialog、modal组件的实现思路;
  2. 写结果
var name = '123';

var obj = {
    name: '456',
    getName: function () {
        function printName () {
            console.log(this.name);
        }

        printName();
    }
}

obj.getName();
  1. 算法题
// 合并两个有序数组
var arr1 = [1, 2, 5, 7, 9];
var arr2 = [3, 4, 6, 8];
  1. 写结果
console.log(0);

setTimeout(() => {
    console.log(1);
});

var data = {};
for (var i = 0; i < 10; i++) {
    data[i] = function () {
        console.log(i);
    }
}

var p = new Promise((res, rej) => {
    console.log(2);
    res(3);
});

p.then(data => {
    console.log(data);
});

console.log(data[8]());

二面

会抓住最近的一个项目开始询问,比如项目中的异常情况,让重新设计一个功能如何去做,并手写业务中的一个工具方法;

反转链表

const list = {
    val:1,
    next:{
      val:2,
      next:{
        val:3,
        next:null
      }
    }
  }
输出
const list = {
    val:3,
    next:{
      val:2,
      next:{
        val:1,
        next:null
      }
    }
  }

实现如下:

const reverse = (list) => {
    let prev = null;
    let curr = list;
    while (curr !== null) {
        let cnext = curr.next;
        curr.next = prev === null ? null : prev;
        prev = curr;
        curr = cnext;
    }
    return prev;
}

三面

会问业务系统的价值、设计业务的时候需要考虑什么? vue和react有什么不一样?

对象数组去重

题目描述:
// 结构相同的两个对象(key数量,key的值,以及key所对应的value的类型和值完全一致),认为是重复项
function dropRepeat(arr) {

}
// 1.数组是对象数组,不存在基础值的场景
// 2.数组中的每一项,均为一层结构的对象,不存在复杂嵌套对象的场景
// 3. 对象中每一个key对应的value值,都是一个基础类型,不存在引用类型
const arr = [{
    a: 1,
    b: 2,
}, {
    b: 2,
    a: 1,
}, {
    c: 1
}, {
    a: '1',
    b: 2
}]

console.log(dropRepeat(arr));
// [{
    a: 1,
    b: 2,
}, {
    c: 1
}, {
    a: '1',
    b: 2
}]

草稿实现:

const dropRepeat2 = (arr) => {
     let newArr = {}; // 
     let res = [];
      for(let i=0, len = arr.length; i < len; i++) {
         
          let keyStr = Object.keys(arr[i]).sort().join();
          let valueStr = Object.values(arr[i]).sort((a, b) => a - b);
            if (newArr[keyStr] && JSON.stringify(valueStr) === JSON.stringify(newArr[keyStr])) 
              continue;
             
          res.push(arr[i])
      }
     return res;
 }