jsx 是什么 在 rn 中的作用是什么
解释 rn 的组件生命周期
什么是虚拟 DOM? 在 rn 中如何工作?
了解 pnpm 原理吗?请陈述一下?
pnpm 原理
观察者模式原理是怎么样的?
观察者模式
Redux 的中间件原理是什么?介绍一些熟悉的中间件。
Redux 中间件原理
js 事件循环的工作机制,为什么是微任务先行
如何在 next.js 应用程序中实现服务端缓存?
服务端缓存的目的是将频繁访问的数据(如 API 响应、页面渲染结果)存储在内存或外部缓存服务中,避免重复计算或查询。Next.js 的服务端运行时(Node.js 环境)支持以下缓存策略:
内存缓存:在进程内存中存储数据,适合小型应用或临时缓存。
外部缓存:使用 Redis、Memcached 等分布式缓存服务,适合高并发场景。
增量静态再生(ISR):Next.js 内置功能,结合静态生成和缓存。
API 路由缓存:通过自定义逻辑缓存 API 响应。
方法 1: 内存缓存(简单实现)
// pages/api/data.js
const cache = new Map();
export default async function handler(req, res) {
const cacheKey = "data";
// 检查缓存是否存在
if (cache.has(cacheKey)) {
console.log("Serving from cache");
return res.status(200).json(cache.get(cacheKey));
}
// 模拟从数据库或外部 API 获取数据
const data = await fetchDataFromSource();
// 存入缓存并设置 TTL(可选)
cache.set(cacheKey, data);
setTimeout(() => cache.delete(cacheKey), 60 * 1000); // 60秒后失效
res.status(200).json(data);
}
async function fetchDataFromSource() {
// 模拟耗时操作
await new Promise((resolve) => setTimeout(resolve, 1000));
return { message: "Hello from source", timestamp: Date.now() };
}
2:使用 Next.js 内置缓存(getServerSideProps) getServerSideProps 的响应默认不缓存,但可以通过自定义头或外部缓存层实现。
// pages/index.js
let cache = null;
let cacheTimestamp = 0;
const CACHE_TTL = 60 * 1000; // 60 秒
export async function getServerSideProps() {
const now = Date.now();
// 检查缓存是否有效
if (cache && now - cacheTimestamp < CACHE_TTL) {
console.log("Serving from server-side cache");
return { props: { data: cache } };
}
// 获取数据并更新缓存
const data = await fetchDataFromSource();
cache = data;
cacheTimestamp = now;
return { props: { data } };
}
async function fetchDataFromSource() {
await new Promise((resolve) => setTimeout(resolve, 1000));
return { message: "Fresh data", timestamp: Date.now() };
}
export default function Home({ data }) {
return (
<div>
{data.message} - {data.timestamp}
</div>
);
}
3: 自定义缓存中间件 在 Next.js 的自定义服务器或中间件中实现缓存逻辑。
// middleware.js
import { NextResponse } from "next/server";
const cache = new Map();
export function middleware(req) {
const cacheKey = req.nextUrl.pathname;
if (cache.has(cacheKey)) {
console.log("Serving from middleware cache");
return NextResponse.json(cache.get(cacheKey));
}
const data = { message: "Middleware data", timestamp: Date.now() };
cache.set(cacheKey, data);
setTimeout(() => cache.delete(cacheKey), 60 * 1000);
return NextResponse.json(data);
}
为什么使用 taildwindcss? 优势在哪里?
原子化 css 类:灵活性与高效开发 Tailwind 提供原子级 CSS 类,每个类对应单一 CSS 属性(如 text-center 表示文本居中,bg-blue-500 表示蓝色背景),开发者通过组合这些类快速构建界面,无需编写大量自定义 CSS。例如:
<button class="px-4 py-2 bg-blue-500 text-white rounded shadow">按钮</button>
优势:
减少重复代码:避免传统 CSS 中重复定义样式,提升开发效率
语义化类名:类名直接反映样式效果(如 hover:text-blue-500),降低记忆负担
模块化:样式与 HTML 绑定,便于组件化开发,减少全局样式污染
Tailwind 内置响应式类前缀(如 sm:、md:),开发者无需编写复杂媒体查询即可适配多设备。例如
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"></div>
优势:
移动优先:默认样式适用于小屏幕,通过前缀覆盖大屏布局
直观控制:直接在 HTML 中管理响应式逻辑,避免分散到 CSS 文件
JIT 模式:Tailwind 的 Just-In-Time 引擎在编译时仅生成实际使用的类,大幅减少 CSS 文件体积
清除未使用样式:通过配置扫描项目文件,自动删除未引用的类,确保生产环境 CSS 最小化
Tailwind 提供配置文件(tailwind.config.js),允许开发者自定义颜色、间距、断点等设计系统参数。例如:
module.exports = {
theme: {
extend: {
colors: {
brand: "#FF5733",
},
},
},
};
http 强缓存和协商缓存的区别是什么?常用字段有哪些?使用场景是什么?
什么是路由懒加载?原理是什么?
说一下对 node 循环机制的理解?
介绍下浏览器渲染的过程?
浏览器的渲染进程
如何解决跨域?
寻找区间
/**
* @param {number[][]} intervals
* @return {number[][]}
*/
var merge = function (intervals) {
const newArr = [];
if (intervals.length === 0) {
return newArr;
}
// 合并区间排序
intervals.sort((a, b) => a[0] - b[0]);
let currentQu = intervals[0];
for (let i = 1; i < intervals.length; i++) {
let nextQu = intervals[i];
if (currentQu[1] >= nextQu[0]) {
// 存在交集
currentQu[1] = Math.max(currentQu[1], nextQu[1]);
} else {
newArr.push(currentQu);
currentQu = nextQu;
}
}
// 把最后一个 currentQu 放入
newArr.push(currentQu);
return newArr;
};
实现 promise.all
function customPromiseAll(iterable) {
const arr = [];
let completedCount = 0; // 用于跟踪完成的 Promise 数量
return new Promise((resolve) => {
if (iterable.length === 0) {
resolve(arr);
return;
}
iterable.forEach((promise, index) => {
Promise.resolve(promise).then((result) => {
arr[index] = result; // 将结果存入对应的位置
completedCount++;
if (completedCount === iterable.length) {
resolve(arr);
}
});
});
});
}
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
customPromiseAll([promise1, promise2, promise3])
.then((reslut) => {
console.log("reslut", reslut);
})
.catch((e) => {
console.log("err", e);
});