小红书一面:长达一个小时的拷打[特殊字符]

前言

兄弟也是好起来了,又又有大厂面试了。


面试过程:

一、自我介绍

这个自我介绍我之前在面试文章中提到过,大家可以翻翻查看。

二、实习经历

面试官看到我目前在一家公司实习,于是让我聊了聊我的业务内容。


三、项目方面

1. 你为什么选用 Tailwind CSS?能说说有什么好处吗?
  • 原子化设计:Tailwind CSS 是一种原子化 CSS 框架,将样式拆分为最小的功能单元,每个类只负责一个特定的样式属性。
  • 开发效率高:像写内联类一样快速编写样式,无需额外创建 CSS 文件。
  • 响应式友好:支持大量响应式类,例如 md:w-1/2lg:w-1/4lg:flex-row 等。
  • 样式隔离性强:在 Vue 单文件组件中使用 Tailwind 类,避免传统 CSS 中的样式冲突问题,比如 TabBar、ShowProducts 等组件各自维护自己的样式。
  • 技术广度体现:其实当时用这个是想展示一下对现代前端工具链的理解。
  • 缺点
    • 学习曲线较陡,需要记忆大量类名和约定;
    • 熟练后开发效率更高。
  • 拓展思考
    • 便于 AI 辅助开发:原子类不依赖嵌套或继承,减少 AI 理解上下文的压力;
    • 降低样式覆盖风险,减少了 CSS 的“层叠”问题和选择器冲突。

2. 你的项目用到了组件懒加载,讲讲好处?
  • 在路由懒加载中使用了组件懒加载,实现 按需加载,只有当用户导航到特定路由时,才会加载相应的组件。
  • 如果不使用懒加载,打包时会把所有页面打包成一个文件,首页一次性加载全部资源,导致加载速度慢,用户体验差。
  • 使用路由懒加载后,首页资源被拆分为多个 chunk 文件(如 app.js, home.js),CSS 同样被拆分。
面试官追问:你知道为什么会这样吗?

我当时没回答上来,但后来查资料得知:

  • import() 的调用处被视为代码分割点,被请求模块及其子模块会被分离为独立的 chunk。
  • Webpack 等构建工具识别 import(),并将动态导入的模块单独打包,从而减小初始加载体积。
  • 总体积不变,但首屏加载资源减少,提升用户体验。

3. 聊聊你项目中的动态组件
  • 在实现一个礼物推荐助手时,我需要展示用户提问与 AI 回答。
  • 为此我封装了两个组件:一个是用户消息组件,一个是 AI 回复组件。
  • 每次对话内容存储在一个数组中,根据标志属性判断渲染哪个组件。
  • 最终通过 Vue 内置的 <component> 标签结合 :is 属性实现了动态组件切换。

4. 你实现 keep-alive 的目的,以及和 v-if / v-show 的区别?应用场景?
  • keep-alive 目的
    • 缓存组件状态(如表单输入、滚动位置);
    • 避免组件频繁销毁重建;
    • 减少 API 请求,提高性能和用户体验。
  • 缓存控制
    • 使用 include="cachedComponents" 属性,只缓存设置了 meta.cache = true 的组件。
v-ifv-show 的区别:
对比项keep-alivev-ifv-show
是否保持状态✅ 是❌ 否✅ 是
渲染机制组件缓存条件为 false 不渲染切换 display 属性
性能切换成本低,适合频繁切换初始化开销小切换快,初始渲染全量
适用场景多 tab 切换、表单缓存不常切换、复杂组件高频切换简单元素

5. 自定义图片懒加载怎么实现的?

流程如下:

scrollTop + offsetTop
=> getBoundingClientRect()
=> IntersectionObserver

从手动计算逐步过渡到现代浏览器 API,性能越来越好。

又问:你了解 HTML 中原生的 lazy 吗?能否讲讲?
  • 原生 HTML 支持懒加载:<img loading="lazy"><iframe loading="lazy">
  • 优点:简单易用,无需 JS,现代浏览器原生支持;
  • 缺点:兼容性一般,IE 不支持,功能有限;
  • 定制性不强,更高级的需求建议使用 IntersectionObserver 自定义实现。
6.响应式布局这方面,你是怎么做的?
  1. 我的项目中,有一个商品展示的功能,使用的是wc-waterfall ,动态的绑定gap和cols两个属性,通过生命周期挂载,添加事件监听,根据屏幕的大小,调整相应的值,来实现响应式布局。
  2. 通过@media声明在不同尺寸下微调样式细节
  3. 商城项目,经常用得到商品的展示,所以我会将它封装成一个组件,方便复用

四、场景题

1.setimeout

这个是一个面试经常问到的题目,但是他问的很细

for(var i=0;i<4;i++){
    setTimeout(function(){
        console.log(i);
    },1000)
}
首先问你输出什么?

由于 var i 的声明具有函数作用域(在这里指全局作用域),所有的 setTimeout 回调函数实际上引用的是同一个 i 变量。当定时器触发时(即循环已经结束),i 的值已经是 4,因此所有回调打印的结果都是 4。在整个循环过程中只有一个 i,最后连着输出四个4.

又问大概在什么时候输出: 因为定时器不一定准,所以是大概的时间,可能就会回答在4秒后了,实际上,执行同步代码的循环后,定时器四个任务,相继执行,因为间隔时间很短,所以就很像四个定时器并发了一样,实际上还是一个又一个执行的。在大概一秒后。

如何输出 0 1 2 3呢?

var => let

  • 块级作用域:在每次 for 循环迭代中,都会创建一个新的 i 实例。这些 i 变量被限制在循环体的块级作用域内。
  • 延迟执行的回调函数:每个 setTimeout 回调函数捕获的是它对应的那个特定的 i 实例。因此,当定时器触发并执行回调函数时,它们能够访问到正确的 i 值,而不是所有回调都指向同一个 i
那我想要每隔大概一秒输出一个数字呢?
  1. 当时我想到了是:
for (let i = 0,time=1000; i < 4; i++,time+=1000) {
    setTimeout(function () {
        console.log(new Date())
        console.log(i);
    }, time);
}
2025-05-18T14:14:54.808Z
0
2025-05-18T14:14:55.806Z
1
2025-05-18T14:14:56.814Z
2
2025-05-18T14:14:57.800Z
3
  1. 还有就是使用闭包加立即执行函数了:
for (var i = 0; i < 4; i++) {
    (function (i) {
        setTimeout(function () {
            console.log(i);
        }, 1000*i);
    })(i);
}

  1. 进阶:

function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

(async function () {
    for (var i = 0; i < 4; i++) {
        await delay(1000);
        console.log(i);
    }
})();

2. 数组求和

const nestedObj = [1, [2, [3, [4, 5]]], 6, 7], 求和。前几天刚好看到了数组和对象的扁平化,刚好就能用上了,不过面试官好像想让我用更简单的方法,我没想出来。

let sum=0
function flattenObject(obj ) {
    for (const item of obj) {
        if (Array.isArray(item)) {
            flattenObject(item);
        } else {
            sum=sum+item;
        }
    }
    return sum;
}
console.log(flattenObject(nestedObj));// [ 1, 2, 3, 4, 5, 6, 7]

学习点其他简单的方法:

  1. 递归
function sum(arr) {
    return arr.reduce((total, item) => {
        return total + (Array.isArray(item) ? sum(item) : item);
    }, 0);
}

const nestedObj = [1, [2, [3, [4, 5]]], 6, 7];
console.log(sum(nestedObj)); // 输出: 28

结语

面了几家大厂后,也有一些心得:

大厂面试一定是穷追猛打,问到你不会为止。所以有些难题回答不出来也没关系。

而面试其实就是一场表演,大家可以在项目中准备几个亮点,自己演练几遍,在面试时流畅表达出来,体现出自己的深度和思考能力,这才是关键!


原文链接:https://juejin.cn/post/7504973778944032808

### 项目管理中的团队协作与沟通方法 在项目管理中,高效的团队协作与沟通是成功的关键因素之一。通过采用适当的技术手段和工具,可以显著提高团队的工作效率和协同能力。 #### 技术手段提升沟通效率 现代技术为团队提供了一系列强大的工具来支持高效的信息共享、文件管理和进度跟踪。这些工具不仅能够减少误解,还能加快决策过程[^1]。以下是几种常见的技术支持方式: - **项目管理软件**:这类软件通常用于规划任务分配、监控进展以及报告成果。它们允许团队成员实时查看项目的最新状态并调整自己的工作计划。 - **即时通讯工具**:为了促进快速交流,许多企业采用了专门设计的企业级聊天应用。这使得即使身处不同地理位置的人也能迅速解决问题或讨论新想法。 #### 推荐使用的在线协作工具 根据实际需求选择合适的协作工具有助于实现更好的效果。下面列举了一些流行的选项及其特点[^2]: - **禅道**: 提供全面的功能覆盖整个产品生命周期, 支持本地化部署适合对数据安全性有较高要求的企业. - **飞书**: 结合了文档编辑器、视频会议等功能的一体化解决方案,特别强调移动办公体验. - **腾讯TAPD (Agile Product Development)**: 定位于敏捷开发流程的支持者角色,适用于希望实践Scrum或其他灵活框架下的中小型企业或者创业公司. ```python # 示例代码展示如何集成API调用某个特定服务(假设为TAPD) import requests def tapd_api_call(workspace_id, api_key): url = f"https://www.tapd.cn/{workspace_id}/api/v1/stories" headers = {"Authorization": f"Bearer {api_key}"} response = requests.get(url, headers=headers) if response.status_code == 200: return response.json() else: raise Exception(f"Error fetching data from TAPD API: {response.text}") result = tapd_api_call('your_workspace_id', 'your_api_key') print(result) ``` 以上脚本展示了怎样通过Python访问TAPD RESTful接口获取故事列表信息作为例子说明自动化操作可能性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值