字节前端工程训练营机试

分为单选题和编程题,记录一下大概的知识点。

单选题

主要考数据结构与算法算法,计算机网络和html,css,js基础。

数据结构与算法

梦回大一还是大二的数据结构与算法考试…
排序题,冒泡排序,快速排序等等。出了两三道吧。
算法复杂度出了一道很简单的题。
二叉树遍历感觉也出了两三道。
还有一道关于栈的问题。

计算机网络

传输层不可靠传输协议是什么
UDP协议。
还有一道DNS报文的题目
只记得A选项是QR为0代表查询,QR为1代表响应了。

html,css,js

如何统一不同浏览器的margin padding?
CSS Reset

* {
  margin: 0;
  padding: 0;
}

似乎还有 Normalize.css,这个要再学习一下。

还有一个 CSS float的问题,问哪一个属于错误的用法
选项中有
A. float: **
B. float: none
C. float: left
D. float: right
总之选A就对了
如何清除父元素高度塌陷
这个我忘记选项是什么了,我暂时还没了解。

  1. ::after 伪元素清除。
  2. 现代方案: display: flow-root
  3. 触发 BFC 法:overflow 属性。缺点是: overflow: hidden 的本职工作是“隐藏溢出的内容”。如果有下拉菜单、阴影、提示框等需要“溢出”父容器的子元素,它们会被裁切掉。

做法属于BFC应用的是:
BFC(Block Formatting Context),块级格式化上下文。
BFC应用:

  1. 清除内部浮动(最常见的应用):父元素内部有浮动子元素(float: left/right),导致父元素高度塌陷。给父元素设置 overflow: hidden;display: flow-root;
  2. 防止垂直外边距折叠(Margin Collapse):在正常的文档流中,相邻的两个兄弟块级元素,它们的垂直外边距margin-topmargin-bottom)会发生“折叠”,合并为两者中较大的那个值。 将其中一个元素(或两个元素分别)用一个新的父元素包裹起来,并为这个父元素触发 BFC(例如 overflow: hidden;)。
  3. 实现自适应两栏/三栏布局:实现一边定宽、另一边自适应的布局?(例如,左侧菜单栏 float: left,右侧主内容区自动填满剩余宽度)。左侧元素 float: left;(定宽)。右侧主内容区触发 BFC(例如 overflow: hidden;display: flow-root;)。
    面试题的另一个问法可能是:“以下哪个属性可以触发 BFC?”
    以下是几种常见的触发方式(做法):
  • overflow: hidden; / auto; / scroll; (最经典的 hack)
  • display: flow-root; (最现代、语义最正确的“BFC 触发器”)
  • float: left; / right; (浮动元素自己会创建一个 BFC)
  • position: absolute; / fixed; (绝对定位元素会创建一个 BFC)
  • display: inline-block;
  • display: table-cell;
  • Flex/Grid 布局的子项 (flex item / grid item)
    下次在面试题中看到 overflow: hidden;display: flow-root; 这些做法时,如果它们是为了解决“高度塌陷”、“外边距折叠”或“两栏布局”问题,那么这就是一次BFC的应用。

js 中的requestAnimationFrame
看了一下js红宝书没有太看明白,这个回头再说好了。
js中关于setTimeoutPromise.then()的输出顺序
js 在执行时会把任务分成三种:

  • 同步任务(Synchronous Code):在调用栈中立即执行的代码
  • 微任务:在当前同步任务执行完毕后,立即执行的任务。Promise.then().catch() 里的回调函数就是最常见的微任务。
  • 宏任务:在同步任务和所有微任务都执行完毕后,才从队列里拿出一个来执行的任务。setTimeout()setInterval() 里的回调函数就是宏任务。
console.log('1. 同步代码:开始');

// 安排一个宏任务
setTimeout(() => {
  console.log('2. 宏任务:setTimeout 1');
}, 0);

// new Promise 的执行器是同步的
new Promise((resolve, reject) => {
  console.log('3. 同步代码:Promise Executor');
  
  // 在 Promise 内部安排一个宏任务
  setTimeout(() => {
    console.log('4. 宏任务:setTimeout 2 (在Promise内部)');
    resolve(); // 在这个宏任务中,Promise 状态变为 fulfilled
  }, 0);

}).then(() => {
  // 当 promise被 resolve() 时,这个 .then() 才会被放入微任务队列
  console.log('5. 微任务:Promise.then 1');
});

// 安排一个立即 resolve 的 Promise
Promise.resolve().then(() => {
  console.log('6. 微任务:Promise.then 2');
});

console.log('7. 同步代码:结束');
  1. 执行console.log('1. 同步代码:开始')
  2. 遇到setTimeout 1 ,将其回调放入宏任务队列
  3. 遇到 new Promise立即同步执行它的 executor 函数。执行 console.log('3. 同步代码:Promise Executor')
  4. 遇到 setTimeout 2,将其回调放入宏任务队列。
  5. 遇到 Promise.resolve().then(),这个Promise立即 resolved,将其 .then 回调放入微任务队列。
  6. 执行 console.log('7. 同步代码:结束')
  7. 清空微任务队列。
  8. 取出第一个宏任务执行。
  9. 再检查微任务队列。
  10. 执行下一个宏任务。在同一个任务中,resolve() 被调用。resolve() 触发了它所关联的 .then,将其回调放入微任务队列。
  11. 清空微任务队列。

编程题

ACM 模式还是有点不太熟悉,回头多刷一下牛客。

给定一组方程,给出A,B,C的值,求该方程组有多少实数解
方程组形式:
X² + A²Y² + C = 0
Y² + Z² + B = 0
Z² + A = 0
感觉是数学题…先把他们都算出来然后讨论就行。

在位数为k的整数中,有多少个数,其每个位上之和为m。
如k=2,m=3,有12,21,30这三个数每个位上的整数之和为3

import functools

def solve_digit_sum(k:int,m:int)->int:
	@functools.lru_cache(None)
	def count_sequences(digits:int,target_sum:int)->int:
		if target_sum < 0:
			return 0
			
		if target_sum > 9*digits:
			return 0
			
		if digits == 0:
			return 1 if target_sum==0 else 0
			
		total_ways = 0
		for d in range(10):
			total_ways += count_sequences(digits - 1,target_sum - d)
		
		return total_ways
		
		
	if k<=0:
		return 0
		
	final_count = 0
	
	for d1 in range(1,10):
		final_count += count_sequences(k-1,m-d1)
		
	return final_count

还有一道题貌似是:
“花费”定义为该简单路径上所有边权值的最大值。一个无向带权简单图,图联通,统计图上有多少不同的节点(u,v),满足他们之间的最小花费为k。
但是感觉太难了,我打算先放一放。


© Shemol 2022 - 2026