字节财经部门前端一面
上一个部门三面挂了,又被另一个部门捞了(更新:又挂了......又被深圳tiktok测开岗捞了,什么鬼,打算后面拒了
开头就是常规的自我介绍和看项目
还问了为什么选择做前端、怎么学的前端
先记一下问题,后面补答案
CSS
问题:(flex布局)讲一讲flex布局?给子元素设置flex:1是什么含义?flex是哪几个属性的简写?flex-shrink默认值是几?剩余空间的分配规则是怎样的?
答:①flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。
②flex-grow定义项目的放大比例(容器宽度>元素总宽度时如何伸展)默认为0,即如果存在剩余空间,也不放大。
③flex-shrink定义了项目的缩小比例(容器宽度<元素总宽度时如何收缩),默认为1,即如果空间不足,该项目将缩小。
③flex-shrink定义了项目的缩小比例(容器宽度<元素总宽度时如何收缩),默认为1,即如果空间不足,该项目将缩小。
④flex-basis设置的是元素在主轴上的初始尺寸,所谓的初始尺寸就是元素在flex-grow和flex-shrink生效前的尺寸,浏览器根据这个属性,计算主轴是否有多余空间,默认值为auto,即项目的本来大小,如设置了width则元素尺寸由width/height决定(主轴方向),没有设置则由内容决定。
下面这个呈现的效果是怎么样的,a和b分别是多宽
html:
<div class="parent"> <div class="a"></div> <div class="b"></div> </div>css:
.parent { display: flex; height: 200px; width: 1000px; background-color: pink; } .a { width: 100px; flex: 1; background-color: skyblue; } .b { width: 100px; flex: 2; background-color: yellow; }
(实测)在chrome中的效果
我说按1:2分配1000(按实际效果来说确实是这样),但是感觉面试官觉得我错了......我迷惑了
是不是浏览器的规则改变了,我试了好多次,只要a和b都有设置flex,对他们设置width都是没有任何改变的,都是按flex的效果显示
JS
问了不会的东西:节流函数,跨域,浏览器存储,nodejs
问题1:怎么判断this指向?
答:①在全局环境中调用就指向window。②作为对象的方法调用就指向该对象。③作为构造函数调用就指向这个新创建的对象。④可以使用apply,call,bind改变this指向。⑤箭头函数中的this与定义时所处的上下文绑定,且不能被改变,箭头函数this指向取决于它外层找到的离它最近的第一个非箭头函数的this。
问题2:(还是关于this的问题)输出什么?
答:输出Heternally(完蛋,面试时说错了......)。
看了阮一峰老师的博客,好像有点懂了。JavaScript 的 this 原理 - 阮一峰的网络日志 (ruanyifeng.com)
重点是函数作为一个复杂类型是单独保存在堆上的,obj.foo作为函数的参数使用时只是传了foo函数的地址进去,当它在Foo函数中运行时,由于Foo函数是全局对象window的方法,所以this指向window,输出Heternally
问题3:script标签的defer和async属性有什么区别
答:这个博客写得挺好的 图解 script 标签中的 async 和 defer 属性 - 掘金 (juejin.cn)
①defer属性(延迟脚本),相当于告诉浏览器立即下载,但是延迟执行。设置了defer属性的脚本会被延迟到整个页面都解析完毕后再运行,先于DOMContentLoaded事件执行,并且按照加载顺序执行。
②async属性(异步脚本),不保证按序执行,可能会阻塞HTML解析,取决于脚本下载完成时HTML是否解析完毕。
问题4:怎么判断一个变量是一个数组?怎么判断一个变量是null?
答:①判断数组用Array.isArray()方法。②null转换为布尔值是false,typeof判断返回object。
编程题
问题1:实现数组扁平化,k是展开的层数
//函数功能:将多层嵌套的数组扁平化,k为展开的层数 function flat(arr, k) { if (k === 0) { return arr; } const len = arr.length; let res = []; for (let i = 0; i < len; i++) { if (Array.isArray(arr[i])) { //注意concat方法是不改变原数组的,所以要重新赋值 res = res.concat(flat(arr[i], k - 1)); } else { res.push(arr[i]); } } return res; } //测试 console.log(flat([1, [2, [3, [4]]]], 2));
问题2:给定一个数组,返回最小的k个数字,数组中可能会有重复数字,不需要去重
用快排的思想
/** * 快排的核心函数,partition分区 * @param {*} arr 数组 * @param {*} start 起始下标 * @param {*} end 结束下标 */ function partition(arr, start, end) { //选最右的数作为pivot const pivot = arr[end]; //指针i初始化为起始下标-1 let i = start - 1; //指针j是从头到倒数第二个数都走一遍 for (let j = start; j < end; j++) { //如果arr[j]比pivot小,就交换arr[i]和arr[j](把小的移到前面去),且i指针前移 if (arr[j] <= pivot) { i++; swap(arr, i, j); } } //最后把pivot换到中间 swap(arr, i + 1, end); //返回pivot的下标 return i + 1; } //交换数组中的两个数 function swap(arr, i, j) { const t = arr[i]; arr[i] = arr[j]; arr[j] = t; } //找出最小的k个数,返回的k个数不一定是有序的 function getLeastNumbers(arr, k) { const len = arr.length; let start = 0; let end = len - 1; let index = partition(arr, start, end); while (index !== k) { if (index > k) { end = index - 1; index = partition(arr, start, end); } else { start = index + 1; index = partition(arr, start, end); } } return arr.slice(0, index); } //测试用例 const arr = [4, 2, 9, 99, 0, 199, 100, 22, 1, 8, 96, 92, 98]; console.log(getLeastNumbers(arr, 3));
计网
问题1:TCP为什么要三次握手?
问题2:TCP与UDP有什么区别?
问题3:TCP怎么保证对方一定能收到包?如果遇到网络拥塞的状况怎么办?
问题4:TCP的滑动窗口是什么意思?
问题5:HTTP的请求方法和请求头有哪些?
操作系统
问题1:进程和线程有什么区别?如果某个线程挂掉了,这个进程会挂掉吗?如果某个线程修改了内存,另一个线程能感知到吗?