一些能记起来的,细碎的面试题
1. 二维数组回环型输出
有一个类似于[[1,2,3],[4,5,6],[7,8,9]]这样的二维数组,要求最后输出[1,2,3,6,9,8,7,4,5],由外到内回环型的输出。
思路:既然是回环型的输出,相当于遍历矩形的四条边。所以要四个点,top,bottom,left和right。然后就是从left到right,从top到bottom,从right到left,从bottom到top。每遍历完一条边,都需要对对应的点自增和自减。因为是从外到内塌缩,所以循环停止的条件是top大于等于bottom,left大于等于right。代码如下
const fn = () => { const a = [ [1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18], ] let top = 0 let bottom = a.length - 1 let left = 0 let right = a[0].length - 1 let res = [] while (top <= bottom && left <= right) { for (let i = left; i <= right; i++) { res.push(a[top][i]) } top++ for (let i = top; i <= bottom; i++) { res.push(a[i][right]) } right-- if (top <= bottom) { for (let i = right; i >= left; i--) { res.push(a[bottom][i]) } bottom-- } if (left <= right) { for (let i = bottom; i >= top; i--) { res.push(a[i][left]) } left++ } } return res } console.log(fn())
2. 写一个TS工具类型,要求能将某个类型里的属性变为可选,注意类型里的属性也可以是更复杂的类型
思路:TS中写工具类型可以类比JS中写函数,TS中用泛型可以比作形参,keyof是取出某个类型中的所有key值,in是遍历,extends是三元运算符。所以这个工具类型是
type DeepOptional<T> = { [P in keyof T]?: T[P] extends object ? DeepOptional<T[P]> : T[P]; };
3. 虚拟列表
思路:首先要有一个元素的高度和整个列表所有元素渲染高度相当,这样视窗高度一定,就可以用滚动事件监听卷曲的高度。其次就是用卷曲高度来计算到底要实际渲染从start到end之间的元素,并且用平移来保证渲染的元素都在可见范围内。当然这是一个简单方案,除此之外还要考虑缓冲区,不定高,滚动条等。具体可以看:
4. 闭包
从表现上来说,如果返回一个函数,或者用函数作为参数就会形成闭包。因为函数有作用域链,这个在函数定义的时候就已经确定了。函数内部可以访问外层作用域的变量,这样某个变量就会一直存在。所以它会有内存泄漏的可能。解决方法是在函数调用结束后置为null,释放闭包空间。具体可看:juejin.cn/post/691147…
5. 找出字符串中最大数字
有一个字符串,'123ac45678dasd3',找出其中最长的数字
思路:其实就是遍历,用isNaN判断是不是数字。是数字就收集起来,非数字略过。代码如下
const str = '123ac45678dasd3' let arr = [] let str1 = '' for (let i = 0; i < str.length; i++) { if (isNaN(str[i])) { if (str1) { arr.push(str1) str1 = '' } } if (!isNaN(str[i])) { str1 += str[i] } } if (str1) { arr.push(str1) } console.log(arr.reduce((a, b) => b.length > a.length ? b : a))
6. 递归输出路由地址
有一个对象
const sidebarMenus = [ { url: "", children: [ { url: "/app", children: [ { url: "/:id/info", children: [], }, { url: "/:id/detail", children: [ { url: "/group", }, ], }, ], }, ], }, ]
要求输出 ['', '/app', '/app/:id/info', '/app/:id/detail', '/app/:id/detail/group']
思路:肯定要用到递归,需要注意就是这个函数需要接受父级路径。代码如下
const f2 = (arr, parent = '') => { let res = [] arr.forEach((i) => { res.push(parent + i.url) if (i.children) { res = res.concat(f2(i.children, parent + i.url)) } }) return res } console.log(f2(sidebarMenus))