2024年【面试题】最新2024前端面试题(1),从思维图到基础再到深入

本文围绕前端面试常见问题,详细解析了虚拟列表、DOM操作的优化策略(如重排重绘、自定义hook)、BEM命名规范、flex布局、跨域原理、HTTP协议特性、CSS布局方法、Promise和事件机制、Redux原理以及TypeScript的Record用法。还讨论了Koa框架的选择和性能优化技巧。
摘要由CSDN通过智能技术生成

最后

资料过多,篇幅有限

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

自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。

地址:前端面试题库

  • 瀑布流列表对于请求过的数据是否做优化?了解虚拟滚动(虚拟列表)吗?

这题是基于我的项目介绍问的。虚拟列表是在处理用户滚动时,只改变列表在可视区域的渲染部分,它可以提高页面渲染性能,减少数据过多时的卡顿。下面是一个简单的虚拟列表demo:

    function FixedSizeList(props){
        const {{containerHeight,itemCount,itemHeight}} = props; // 容器高度,列表数量,列表项高度
        const [scrollTop,setScrollTop] = useState(0)
        const items = [];
        // 渲染列表第一个index
        let startIdx = Math.floor(scrollTop / itemHeight);
        // 渲染列表最后一个index
        let endIdx = Math.floor((scrollTop+containerHeight)/itemHeight);
        // 在可视区外缓存列表项数量
        const paddingCount = 2;
        startIdx = Math.max(startIdx - paddingCount,0);
        endIdx = Math.min(endIdx + paddingCount,itemCount-1)

        for(let i = startIdx;i <= endIdx;i++) {
            items.push(<Component key={i} index={i}
                    style={{height:itemHeight}}/>)
        }   
        const top = startIdx * itemHeight;
        const contentHeight = itemHeight * itemCount; 

        return (
            <div style={{height:containerHeight,overflow:'auto'}}
                onScroll={
                    (e) => {
                        // 处理渲染有导致的白屏问题
                        // 改为同步更新
                        flushSync(() => {
                            setScrollTop(e.target.scrollTop)
                        })
                    }
                }
            >
                <div style={{height:contentHeight}}>
                    <div style={{height:top}}></div>
                    {items}
                </div>
            </div>
        )
    }
复制代码
  • 重排重绘

重排:当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。修改元素的尺寸、增加删除可见的元素、操作Offset相关属性等都会引起重排。
重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。如修改元素的颜色等。
如何减少重排、重绘:

  1. 分离读写操作:即在使用offset相关属性进行读操作之前,完成所有改变DOM的写操作。
  2. 集中改变样式:将样式统一写在一个类名上,再将该类名加到属性上。
  3. 离线修改dom:在要操作dom之前,通过display隐藏dom,当操作完成之后,才将元素的display属性为可见;或者通过使用DocumentFragment创建一个dom碎片,在它上面批量操作dom,操作完成之后,再添加到文档中,这样只会触发一次重排。
  4. 设置position属性为absolutefixed
  5. 启用gpu加速:transform: translate3d(10px, 10px, 0);
  • 虚拟DOM
  • 类组件/函数组件开发区别
  • 实现自定义hook (对可以上下/左右滑动的滑块定义hooks)

平时自己写自定义hooks比较少,所以这题面试官引导了挺久,还是没写出来/(ㄒoㄒ)/

 const onSlide = (dir) => {
    console.log(dir)
  }
  const { domRef:domRef1 } = useSlide(onSlide,'v');
  const { domRef:domRef2 } = useSlide(onSlide,'h');

  return (
        <div className="App">
          <input type="range" ref={domRef1}/>
          <input type="range" ref={domRef2} style={{transform:'rotate(-90deg)',marginTop:'55px'}}/>
        </div>
      )
复制代码
// 自定义 hooks  useSlide
const useSlide = (cb,direction) => {
    const domRef = useRef(null);

    const handleUp = (e) => {
        if(direction==='v'){
            // cb(e.clientX)
            cb(e.target.value);
        }else if(direction==='h'){
            // cb(e.clientY)
            cb(e.target.value)
        }
    }

    useEffect(() => {
        domRef.current.addEventListener('mouseup',handleUp)
        return () => {
            domRef.current.removeEventListener('mouseup',handleUp)
        }
    },[])

    return {
        domRef
    }
}
复制代码
  • js数据类型,简单数据类型和复杂数据类型的区别
  • 原型链 原型对象
  • Promise与js事件机制
  • 数组扁平化(堆栈写法,非递归)
const flatter = (arr) => {
    let stack = [...arr];
    let res = [];
    while(stack.length){
        let num = stack.pop();
        if(Array.isArray(num)) {
            stack.push(...num);
        } else {
            res.push(num);
        }
    }
    return res.reverse();
}
复制代码
  • 玩石子游戏(算法)
    一共n颗石子,两个人轮流拿,每次可以拿1或2或3颗,最后一次将石子取完的人输,判断自己最后是赢是输?

我一开始想能不能用动态规划去解,面试官说我想复杂了。当最后剩 4 颗石子的时候,无论我们怎么取都可以获胜;当剩 8 颗石子的时候,我们一定可以控制最后剩下 4 颗石子…所以我们只要 判断石子的数量是否是 4 的倍数 即可判断自己最后是否可以获胜。


哈啰 已oc
面试官非常年轻,好像就已经是技术专家了,好羡慕,人也很好,整体面下来的感觉还是不错的。
复制代码
  • cors跨域原理

通过设置响应头Access-Control-Allow-xxx字段来设置访问的白名单、可允许访问的方式等

module.exports = async (ctx,next) => {
    // 设置响应头
    // 允许访问跨域服务的白名单 *允许所有
    ctx.set('Access-Control-Allow-Origin','*'); 
    ctx.set('Access-Control-Allow-Headers','Content-Type');
    ctx.set('Access-Control-Allow-Methods','GET,POST,OPTIONS');
    // OPTIONS 获取资源允许访问的方式
    // 其实在正式跨域之前浏览器会根据需要发起一次预检也就是option请求用来让服务端返回允许的方法
    await(next())
}
复制代码
  • 跨域拦截 是浏览器拦截还是服务器拦截

跨域是浏览器的同源策略造成的,同源是指"协议+域名+端口"三者相同,为了保证浏览器安全对响应的数据进行拦截,若发现是非同源的资源浏览器进程会把响应体丢弃。所以跨域拦截是浏览器进行拦截

跨域是为了阻止用户读取到另一个域名下的内容,跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了。Ajax 可以获取响应,浏览器认为这不安全,所以拦截了响应。通过表单的方式可以发起跨域请求,因为表单并不会获取新的内容,所以可以发起跨域请求。

  • 假设我现在在淘宝,要去百度,我还会携带上淘宝的cookie吗?

不会。cookie中,domain 属性指定了 cookie 的所属域名,path 属性用来指定路径;这两个属性决定了服务器发送的请求是否带上这个cookie。淘宝的 cookie 和百度的域名、路径不一致,所以访问百度不会带上淘宝的cookie

  • 淘宝跳转到天猫页面为什么不需要重新登陆( taobao.com 和 tmall.com )?

这是因为淘宝和天猫页面设置了单点登录SSO,在多个系统的集群里,用户只需一次登陆,其他系统也会感知到用户登陆,不需要用户重新输入用户名密码登陆。

在淘宝和天猫之间部署一台专门用作登录的服务器,相当于实现一个中转站,这个中转站存放着需要共享登录状态服务应用的 session 信息,它就相当于一把钥匙,当用户进行应用跳转的时候都会来中转站看一看,如果 session 存在就直接使用这把钥匙把通往另一个应用的门打开,如果不在就得先确认用户身份(登录)制造 session 钥匙存在中转站再把门打开,用户的身份存储和身份的有效时间都是中转站说了算,统一管理的。

  • http协议的特点
  1. 灵活方便:支持传输多种形式的内容
  2. 可靠传输:基于tcp/ip
  3. 请求-应答:具有发送方和接收方
  4. 无状态:每次请求都是独立无关的,不会记住上一次的状态
  • BEM 命名规范

B:block E:element M:modefiled 语义性好,模块化,组件化,可复用
这是面试官看到我的掘金第一篇文章来问的,有兴趣的朋友可以看看哦。BEM-实战淘宝订单模块

  • flex:1的含义, flex:1和flex:2的区别

flex 是 flex-grow ,flex-shrink ,flex-basis的缩写
flex:1
flex-grow:1若存在剩余空间根据剩余空间进行放大 ;
flex-shrink:1若空间不够,将内容缩小;
flex-basis:0% 内容本来大小

  • var a = [],为什么可以直接使用a.push(),a.pop()

a 通过对象字面量的方式生成一个数组对象实例,可以通过原型链查找方法,使用到Array原型上的pushpop方法。

  • var a = new A(),a 和 A 的关系,A 和 Function 的关系

a 是 A 的一个实例对象,a 的__proto__ 指向 A 的 prototype,A 的__proto__ 指向 Function 的 prototype

  • 浏览器事件机制 event loop
  • Primise.then 中的微任务在下一轮还是这一轮执行
  • commonjs之后为什么提出es molule,两个模块的特点

commonjs 导出(module.exports),导入(require)。
可以动态加载语句,发生在代码运行时,模块是同步加载的,只要加载完成才能进行后续操作;模块可以多次加载,但只会在第一次加载时运行一次,结果会被缓存,下次 加载直接读取缓存结果,除非清除缓存。导出的值的拷贝的,可以修改,模块内的修改不会影响拷贝的值,代码出错不好排查。
esmodule 导出(export default),导入(import from)
静态的,只能声明在文件最顶部,发生在代码编译时;导出的值存在映射关系引用,是可读的,不可修改

  • 函数式组件和类组件的区别
  • usestate 重复修改多次,会渲染多次吗? 什么时机触发渲染?
  • 如果useState同步代码中重复修改多次,只会渲染一次。因为出于性能考虑,React 会把多个 setState() 调用合并成一个调用,这也是state批量更新机制。React 会将该 state “冲洗” 到浏览器事件结束的时候,再统一地进行更新,这时才会触发渲染。
  • 而如果setState异步代码(如 setTimeout、async await)中重复修改多次,渲染会在每次修改后触发一次。
  • redux
  • 听说过基于redux的封装吗?
  • 为什么本地开发更改一行代码,浏览器会局部更新那一部分?浏览器怎么知道代码变了?

这题触及到我的知识盲区了,于是面试官跟我讲解了一下,赞!
脚手架npm run dev后,会启动一个本地的服务 localhost,它基于socket 连接本地编辑器和浏览器的通信,监听文件系统是否发生改变,当发生改变时webpack 会告诉浏览器代码发生更改,浏览器就会做相应的渲染。这块应该是热更新的知识点。

  • 装饰者模式
  • ts 中 record是做什么的?

Record<K,T>构造具有给定类型T的一组属性K的类型。他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型.

实例:

interface EmployeeType {
    id: number
    fullname: string
    role: string
}

let employees: Record<number, EmployeeType> = {
    0: { id: 1, fullname: "John Doe", role: "Designer" },
    1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
    2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}

// 0: { id: 1, fullname: "John Doe", role: "Designer" },
// 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
// 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }
复制代码
  • 项目后台搭建为什么选择koa?为什么不是express?
  • 说说个人的亮点

给大家推荐一个实用面试题库

**1、前端面试题库 (**面试必备) 推荐:★★★★★

地址:前端面试题库

滴滴 已oc
感觉面试官问的问题可回答面比较广,所以可以挑自己擅长的领域说~ 而且面试官比较和蔼,让我不要紧张。面试官直接就跟我约了二面的时间。
复制代码
  • css布局方式

说了以下四种布局方式,然后以水平垂直居中为例,具体的说了下每种布局方式是如何使用的。

  1. flex
  2. grid
  3. float
  4. position
  • float离开文档流怎么做处理

我大概说了下清浮动、高度塌陷的不同处理方式,顺便说了下BFC

基础面试题

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

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

我约了二面的时间。
复制代码


* css布局方式



> 
> 说了以下四种布局方式,然后以水平垂直居中为例,具体的说了下每种布局方式是如何使用的。
> 
> 
> 
> 	1. flex
> 	2. grid
> 	3. float
> 	4. position
>
* float离开文档流怎么做处理



> 
> 我大概说了下**清浮动、高度塌陷**的不同处理方式,顺便说了下BFC
> 
> 
>


### 基础面试题

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

> 主要内容包括:**HTML,CSS,JavaScript,浏览器,性能优化等等**

[外链图片转存中...(img-zrdUvAGW-1714975193140)]

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2024前端面试题可能会涉及以下几个方面的内容: 1. HTML/CSS基础知识:包括HTML标签的使用、CSS选择器、盒模型、浮动、定位等基本概念和常见问题。 2. JavaScript基础知识:包括数据类型、变量、运算符、流程控制语句、函数、作用域、闭包等基本概念和常见问题。 3. 前端框架和库:例如React、Vue等,可能会涉及到它们的基本原理、生命周期、组件通信等方面的问题。 4. 前端性能优化:包括减少HTTP请求、压缩和合并文件、使用CDN加速、懒加载、缓存等方面的知识。 5. 前端工程化:包括模块化开发、构建工具(如Webpack)、版本控制(如Git)、自动化测试等方面的知识。 6. 前端安全:包括XSS攻击、CSRF攻击、点击劫持等常见安全问题及其防范措施。 7. 前端跨域问题:包括同源策略、跨域请求的方法(如JSONP、CORS等)以及解决跨域问题的方案。 8. 移动端开发:包括响应式设计、移动端适配、触摸事件、移动端性能优化等方面的知识。 9. Web标准和浏览器兼容性:包括HTML5、CSS3的新特性以及不同浏览器之间的差异和兼容性问题。 10. 数据可视化:包括使用图表库(如Echarts、D3.js)进行数据可视化的基本原理和常见问题。 以上只是一些可能涉及到的内容,具体的面试题目还会根据面试官的要求和公司的需求而有所不同。在准备面试时,建议多做一些实际项目练习,加深对前端知识的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值