笔试记录(2)

97 阅读5分钟

2024.5.21 海康威视

前端基础题目和计算机基础素养题目64开,后者包含了数据结构(二叉树,常考)、操作系统(进程线程)、算法(排序)——但是没有网络的题!

体验:一般。有些题存在表意不清问题偏老等问题。两道算法题很基础。 下面只讲些自己掌握不扎实需要反思总结的题目。如有讲错,请掘友指正!🤖

1.css选择器权重问题
.wrapper {
    color: blue;
}
.inner {
    color: white;
}
span {
    color: green;
}

 
<div class="wrapper" style="color: red !important">
    <span class="inner">test</span>
</div>

test字体颜色是?—————— white(我错选成了red)

个人理解:还是 就近原则 优先

2.Object.is 和 ===

Object(NaN, NaN) 为true; Object(+0, -0) 为false

NaN === NaN 为false; +0 === -0 为true

3. ES6的import()

以下哪个选项描述了import()函数的正确用法?

A.import()函数返回一个Promise对象,用于异步加载模块

B.import()函数可以用来导入CSS文件

C.import()函数只能在浏览器环境中使用

D.import()函数只能导入ES6模块,不能导入CommonJS模块

我选 A (不大确定) (import和import()不同)

4.position:fixed

关于position定位,下列说法正确的是()(多选)

A.fixed 属性的元素在标准流中不占位置

B.fixed元素,可定位于相对于浏览器窗口的指定坐标,它始终是以 body 为依据

C.relative元素以它原来的位置为基准偏移,在其移动后,原来的位置不再占据空间

D.absolte 的元素,如果它的 父容器设置了 position 属性,并且 position 的属性值为 absolute 或者relative,那么就会依据父容器进行偏移

我选AD。 这里 B 要展开讲一下:

首先是定义fixed的定义:元素相对于第一个 containing block包含块(或视觉媒体元素的视口)的定位,且最终位置由top、right、bottom、left 的值决定。

fixed 定位的元素的包含块指向三种:

  1. 视口
  2. 距离最近的复合图层元素(设置了transform、filter、will-change等属性的父级元素)
  3. contain隔离内容

所以针对2,3有两个方法: 给fixed元素某个祖先元素 设置可以新建复合图层的属性 或 设置css的 contain 属性:

可以新建复合图层的属性:

  • transform
  • perspective
  • filter
  • backdrop-filter
  • will-change

(这些属性可以启用 GPU 硬件加速,原理是:使用后,1.渲染引擎会把该把元素单独分层交给 GPU 渲染,GPU处理图形计算更快 2.分层渲染不会造成页面的回流重绘)

关于contain属性:该属性可以隔离某个 DOM 元素,即将布局、样式、绘制、大小或任何组合的计算限制为 某个DOM 子树而不是整个页面。详细介绍见MDN。(contain 隔离属性除了遏制布局以外,最大的好处就是改善性能——减少不必要的重绘和重排)

5.正则匹配 —— match,matchAll,exec

let s = "Hello World, this my World!";
console.log(s.match(/World/g));
console.log(s.match(/World/));
console.log([...s.matchAll(/World/g)]);
console.log([...s.matchAll(/World/)]);
while ((match = /World/g.exec(s)) !== null) {
  console.log(
    `找到 ${match[0]} 起始位置=${match.index} 结束位置=${regexp.lastIndex}。`,
  );
}

//输出:
//第二行:[ 'World', 'World' ]
//第三行:
[
  'World',
  index: 6,
  input: 'Hello World, this my World!',
  groups: undefined
]
//第四行:
[
  [
    'World',
    index: 6,
    input: 'Hello World, this my World!',
    groups: undefined
  ],
  [
    'World',
    index: 21,
    input: 'Hello World, this my World!',
    groups: undefined
  ]
]
//第五行:报错,不能没有g
//第六行:
找到 World 起始位置=6 结束位置=10。
找到 World 起始位置=21 结束位置=25

match返回数组,matchAll返回迭代器,exec返回数组但需要多次执行

substr方法已经废弃了,只有substring(start,end)

6.重排(回流)和重绘,以及如何减少

(考试的时候只回答定义和如何减少了,如果答了 哪些操作 会引起重排重绘更好)

重排:DOM的变化影响了元素的几何信息(的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置

重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来

重排一定引起重绘,反之不然

减少重排重绘: 减少范围——局部重排,比如用contain;别用table之类 减少次数——样式集中改变,动态添加类名,读写分离;DOM离线处理;脱离文档流处理;启用GPU加速

7.其他

console.log(0 && 1) 输出0 (0为false,则直接返回)

对于有序度较高的数组,插排比冒泡排序和选择排序要快(这三个我一直分不清觉得挺像的)

parseInt('6.9') == 6.9 (字符串 => 整数, 且向下取整)

react的任务优先级就是用 堆 实现的,建堆最快O(n)

进程是资源分配的最小单位,线程是运行调度的最小单位 (juejin.cn/post/684490… 这篇讲Nodejs中的进程线程的文章挺好)

趁此简单回忆下nodejs中的事件循环(之前阿里一面直接说不会🤭):

  • 首先明白一件事,Node底层使用的libuv是c++写的一个高性能解决单线程非阻塞异步 I/O 的开源库,操作底层的操作系统,封装了操作系统的接口供Node使用。Node的事件循环也是用libuv来写的

  • 六个事件队列(按顺序timer——setTimeoutsetInterval的回调,pending callback——setTimeoutsetInterval的回调, idle prepare——系统内部使用 一般开发者用不到, poll——timers、check之外的回调存放在这里 如IO文件读写, check——setImmediate的回调, close callback——close事件的回调)和一个微任务队列(nextTick, Promise)

  • 对浏览器来说每当一个宏任务执行完成之后就会清空一次微任务队列,而在 node 中只有在事件队列切换时才会去清空微任务队列 且nextTick的执行优先级要高于Promise

算法是一道 递归拼接树形结构 的题:

getTreeList(rootList, parentId, children){
    
    //找到所有父亲为parentId的节点
    for(let item of rootList){
        if (item.pid = parentId){
            children.push(item)
        }
    }
    
    //再找这些节点的孩子
    for(let item of children){
        item.children = []
        getTreeList(rootList, item.pid, item.children)
    }
    
    return children[0]
}

//祖宗的父亲为null
const res = getTreeList(data, null, [])

还有一道简单的算法题是将秒数转化成 时:分:秒 格式,但我只过了75%,不知道为啥..

结语

不知道能不能过,明天还有一个小公司的二面,先去再看看react喽 🧢