2024年最全10个常见的前端手写功能,你全都会吗?(3),高级程序员面试题java

数据结构与算法

这一块在笔试、面试的代码题中考核较多,其中常考的数据结构主要有:数组、链表、队列、栈、Set、Map、哈希表等,不同数据结构有不同的方法以及储存原理,这些算是技术岗的必备知识。算法部分主要分为两大块,排序算法与一些其他算法题

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

排序算法根据考频高低主要有:快速排序、归并排序、堆排序、冒泡排序、插入排序、选择排序、希尔排序、桶排序、基数排序、Timsort这十种,这类考核点要么是算法的时间、空间复杂度、稳定度,要么是直接手写代码,故在理解算法原理的同时,对JS语言版的排序算法代码也要加强记忆。

  • 二叉树层序遍历
  • B 树的特性,B 树和 B+树的区别
  • 尾递归
  • 如何写一个大数阶乘?递归的方法会出现什么问题?
  • 把多维数组变成一维数组的方法
  • 知道的排序算法 说一下冒泡快排的原理
  • Heap 排序方法的原理?复杂度?
  • 几种常见的排序算法,手写
  • 数组的去重,尽可能写出多个方法
  • 如果有一个大的数组,都是整型,怎么找出最大的前 10 个数
  • 知道数据结构里面的常见的数据结构
  • 找出数组中第 k 大的数组出现多少次,比如数组【1,2, 4,4,3,5】第二大的数字是 4,出现两次,所以返回 2
  • 合并两个有序数组
  • 给一个数,去一个已经排好序的数组中寻找这个数的位 置(通过快速查找,二分查找)

function throttle(fn, delay) {

let last = 0 // 上次触发时间

return (…args) => {

const now = Date.now()

if (now - last > delay) {

last = now

fn.apply(this, args)

}

}

}

// 测试

function task() {

console.log(‘run task’)

}

const throttleTask = throttle(task, 1000)

window.addEventListener(‘scroll’, throttleTask)

3、深拷贝

function deepClone(obj, cache = new WeakMap()) {

if (typeof obj !== ‘object’) return obj // 普通类型,直接返回

if (obj === null) return obj

if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环

if (obj instanceof Date) return new Date(obj)

if (obj instanceof RegExp) return new RegExp(obj)

// 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数

let cloneObj = new obj.constructor()

cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况

for (let key in obj) {

if (obj.hasOwnProperty(key)) {

cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝

}

}

return cloneObj

}

// 测试

const obj = { name: ‘Jack’, address: { x: 100, y: 200 } }

obj.a = obj // 循环引用

const newObj = deepClone(obj)

console.log(newObj.address === obj.address) // false

4、实现 Promise

class MyPromise {

constructor(executor) { // executor执行器

this.status = ‘pending’ // 等待状态

this.value = null // 成功或失败的参数

this.fulfilledCallbacks = [] // 成功的函数队列

this.rejectedCallbacks = [] // 失败的函数队列

const that = this

function resolve(value) { // 成功的方法

if (that.status === ‘pending’) {

that.status = ‘resolved’

that.value = value

that.fulfilledCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法

}

}

function reject(value) { //失败的方法

if (that.status === ‘pending’) {

that.status = ‘rejected’

that.value = value

that.rejectedCallbacks.forEach(myFn => myFn(that.value)) //执行回调方法

}

}

try {

executor(resolve, reject)

} catch (err) {

reject(err)

}

}

then(onFulfilled, onRejected) {

if (this.status === ‘pending’) {

// 等待状态,添加回调函数到成功的函数队列

this.fulfilledCallbacks.push(() => {

onFulfilled(this.value)

})

// 等待状态,添加回调函数到失败的函数队列

this.rejectedCallbacks.push(() => {

onRejected(this.value)

})

}

if (this.status === ‘resolved’) { // 支持同步调用

console.log(‘this’, this)

onFulfilled(this.value)

}

if (this.status === ‘rejected’) { // 支持同步调用

onRejected(this.value)

}

}

}

// 测试

function fn() {

return new MyPromise((resolve, reject) => {

setTimeout(() => {

if(Math.random() > 0.6) {

resolve(1)

} else {

reject(2)

}

}, 1000)

})

}

fn().then(

res => {

console.log(‘res’, res) // res 1

},

err => {

console.log(‘err’, err) // err 2

})

5、异步控制并发数

function limitRequest(urls = [], limit = 5) {

return new Promise((resolve, reject) => {

const len = urls.length

let count = 0 // 当前进行到第几个任务

const start = async () => {

const url = urls.shift() // 从数组中拿取第一个任务

if (url) {

try {

await axios.post(url)

if (count == len - 1) {

// 最后一个任务

resolve()

} else {

count++

// 成功,启动下一个任务

start()

}

} catch (e) {

count++

// 失败,也启动下一个任务

start()

}

}

}

// 启动limit个任务

while (limit > 0) {

start()

limit -= 1

}

})

}

// 测试

limitRequest([‘http://xxa’, ‘http://xxb’, ‘http://xxc’, ‘http://xxd’, ‘http://xxe’])

6、ES5继承(寄生组合继承)

function Parent(name) {

this.name = name

}

Parent.prototype.eat = function () {

console.log(this.name + ’ is eating’)

}

function Child(name, age) {

Parent.call(this, name)

this.age = age

}

Child.prototype = Object.create(Parent.prototype)

Child.prototype.contructor = Child

Child.prototype.study = function () {

console.log(this.name + ’ is studying’)

}

// 测试

let child = new Child(‘xiaoming’, 16)

console.log(child.name) // xiaoming

child.eat() // xiaoming is eating

child.study() // xiaoming is studying

7、数组排序

sort 排序

// 对数字进行排序,简写

const arr = [3, 2, 4, 1, 5]

arr.sort((a, b) => a - b)

console.log(arr) // [1, 2, 3, 4, 5]

// 对字母进行排序,简写

const arr = [‘b’, ‘c’, ‘a’, ‘e’, ‘d’]

arr.sort()

console.log(arr) // [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]

冒泡排序

function bubbleSort(arr) {

let len = arr.length

for (let i = 0; i < len - 1; i++) {

// 从第一个元素开始,比较相邻的两个元素,前者大就交换位置

for (let j = 0; j < len - 1 - i; j++) {

if (arr[j] > arr[j + 1]) {

let num = arr[j]

arr[j] = arr[j + 1]

arr[j + 1] = num

}

}

// 每次遍历结束,都能找到一个最大值,放在数组最后

}

return arr

}

//测试

console.log(bubbleSort([2, 3, 1, 5, 4])) // [1, 2, 3, 4, 5]

文末

如果30岁以前,可以还不知道自己想去做什么的话,那30岁之后,真的觉得时间非常的宝贵,不能再浪费时间在一些碎片化的事情上,比如说看综艺,电视剧。一个人的黄金时间也就二,三十年,不能过得浑浑噩噩。所以花了基本上休息的时间,去不断的完善自己的知识体系,希望可以成为一个领域内的TOP。

同样是干到30岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。

这也是为什么大家都说30岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。

269页《前端大厂面试宝典》

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

闪耀不被公司淘汰不被社会淘汰。

269页《前端大厂面试宝典》

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值