真的是非常顺畅的一次面试,体验非常棒,面试官的态度和专业知识也非常到位!

1.如何学习前端

2.JS和CSS的一些新特性

3.如何实现一个高精度的定时器

  • raf(视觉相关)
  • 自校准的setTimeout+performance.now(),performance.now()是一个高精度的时间戳,不受系统时间修改的影响,精度远高于 Date.now()
  • 使用Web Worker

4.使用web worker的话,传递回主线程会被主线程正在进行的任务阻塞吗?

会,优先级类似于微任务

5.absolute的定位是基于谁,fixed的定位是基于什么?

absolut基于最近的已经定位的父级元素,fixed基于视口,window

6.z-index的作用范围?

层级作用域,在同一层级才会生效

7.tcp和udp的区别和使用场景

8.同源策略,跨域和跨站

9.浏览器的并发上限,如何突破这个上限?

  • 一般是六个
  • HTTP2.0的版本通过多路复用解决了这个问题
  • 不是HTTP2.0的版本可以通过域名分片,也就把不同的静态资源分布到多个子域名中,可以进行资源打包和雪碧图类似的想法减少资源请求;或者使用Websocket

10.React和Vue提供的hooks和函数解决了什么问题?

提高逻辑可复用性,从按生命周期/选项来组织逻辑到按逻辑关注点来组织

11.了解哪些React的新特性

12.改代码:React useCallback相关

13.一次遍历找到数组中第k大的元素,如何做?

最小堆或者快速选择比较常见

//最小堆
function findKthLargest(nums, k) {
	const minHeap = new MinHeap();
	
	for(const num of nums) {
		if (minHeap.size() < k) {
			minHeap.push(num);
		} else if (num > minHeap.peek()) {
			minHeap.pop();
			minHeap.push(num);
		}
	}
	
	return minHeap.peek();
}
// 快速排序,核心思想就是减治
function swap(arr, i, j) {
	[arr[i], arr[j]] = [arr[j], arr[i]];
}

function partition(nums, left, right) {
	const pivotValue = nums[right];
	let storeIndex = left;
	
	for (let i = left; i < right; i++) {
		if (nums[i] < pivotValue) {
			swap(nums, storeIndex, i);
			storeIndex++;
		}
	}
	swap(nums, storeIndex, right);
	return storeIndex;
}

function findKthLargest(nums, k) {
	const n = nums.length;
	const targetIndex = n - k;
	let left = 0;
	let right = n - 1;
	
	while (left <= right) {
		const pivotIndex = partition(nums, left, right);
		
		if (pivotIndex === targetIndex) {
			return nums[pivotIndex];
		} else if (pivotIndex < targetIndex) {
			left = pivotIndex + 1;
		} else {
			right = pivotIndex - 1;
		}
	}
}
方法时间复杂度 (平均)空间复杂度是否一次遍历是否修改原数组
最小堆法O(n log k)O(k)
快速选择法O(n)O(log n) 递归栈是 (in-place)
排序法O(n log n)O(log n) 排序栈是 (in-place)

14.了解哪些排序算法,对于全国人民的身高,用什么排序方法比较好?

  • 桶排序

15.手撕:判断二叉树是否为平衡二叉树

16.项目相关

帆软前端二面

作者

MeorinLime 梦灵

发布日期

2025 - 09 - 04