
1) 【一句话结论】
构建分层动态缓存体系,根据网络环境(Wi-Fi/4G)动态调整内存(10MB)与磁盘(Wi-Fi 5GB/4G 2GB)缓存大小,结合LRU淘汰机制,并针对视频流式播放按秒分段缓存(4G下缓存3秒片段,Wi-Fi下缓存10秒片段),确保加载速度与资源占用平衡。
2) 【原理/概念讲解】
老师解释:缓存策略的核心是分层存储与动态适配。分层缓存分为三部分:内存缓存(RAM,快但容量小,适合高频访问的图片,如首页缩略图,通过LRU淘汰最久未用资源);磁盘缓存(SSD,慢但容量大,适合视频等大文件,通过LRU+基于大小的淘汰控制空间);网络缓存(CDN,远程加速,用于加速资源获取)。资源版本控制:通过请求头中的ETag(动态指纹,如图片内容变化时更新)或Last-Modified(时间戳,静态资源更新频率低),客户端缓存资源后,下次请求时带上,服务器比较后若资源未更新则返回304(不更新),避免重复下载。淘汰机制:LRU(最近最少使用)维护资源访问时间,淘汰最久未使用的资源,适用于“先热门后冷门”的访问模式;基于大小的淘汰结合LRU,控制磁盘空间,确保磁盘空间不超过预设阈值(如Wi-Fi下5GB,4G下2GB)。
3) 【对比与适用场景】
| 策略类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 内存缓存(LRU) | 基于资源访问时间排序,淘汰最久未使用的资源(最近最少使用) | 速度快,适合高频访问,访问模式“先热门后冷门” | 图片、小视频等高频访问资源(如首页缩略图、动态图标) | 需维护访问时间记录,避免冷启动(首次访问时缓存为空);内存大小设为10MB,避免内存溢出 |
| 磁盘缓存(LRU+大小) | 固定磁盘空间限制(如Wi-Fi 5GB,4G 2GB)+LRU淘汰机制 | 控制磁盘空间,避免大文件占用过多存储;结合LRU优化访问效率 | 视频等大文件(如长视频片段、大图片资源) | 需动态调整磁盘空间限制(根据网络环境),结合LRU避免冷启动;磁盘写入性能需考虑(如SSD比HDD快,但4G下仍需控制写入频率) |
| 视频流式缓存(分段+动态调整) | 按视频秒分段(如1秒为一段),优先缓存当前及后续片段,淘汰远期片段;根据网络速度动态调整缓存片段数量(4G下缓存3秒,Wi-Fi下缓存10秒) | 支持断点续传,提升播放体验;根据网络带宽动态调整缓存大小,优化资源占用 | 视频流式播放场景(如视频播放器) | 需实时测速API获取当前带宽,动态计算缓存片段数量;4G下缓存片段少,避免4G网络下加载大视频导致卡顿;Wi-Fi下缓存片段多,提升播放流畅度 |
4) 【示例】
伪代码(请求流程+淘汰逻辑):
// 缓存策略初始化(根据网络类型调整)
function initCache(networkType) {
if (networkType === 'wifi') {
memoryCacheSize = 10MB; // 内存缓存大小
diskCacheSize = 5GB; // 磁盘缓存大小
videoCacheDuration = 10; // 视频缓存片段数(秒)
} else if (networkType === '4g') {
memoryCacheSize = 10MB;
diskCacheSize = 2GB;
videoCacheDuration = 3;
}
// 初始化LRU缓存
memoryCache = new LRU(memoryCacheSize);
diskCache = new LRU(diskCacheSize);
}
// 加载资源(图片/视频)
function loadResource(url, networkType) {
// 1. 检查内存缓存(带版本校验)
if (memoryCache.has(url)) {
cached = memoryCache.get(url);
if (cached.version === serverVersion(url)) {
return cached.data;
}
}
// 2. 检查磁盘缓存
if (diskCache.has(url)) {
diskRes = diskCache.get(url);
memoryCache.put(url, { data: diskRes.data, version: diskRes.version });
return diskRes.data;
}
// 3. 网络请求(带版本信息)
response = fetchFromNetwork(url, {
headers: {
'If-None-Match': memoryCache.get(url)?.version || '',
'If-Modified-Since': memoryCache.get(url)?.lastModified || ''
}
});
if (response.status === 304) {
return memoryCache.get(url)?.data;
}
if (response.ok) {
newRes = {
data: response.data,
version: response.headers.get('ETag'),
lastModified: response.headers.get('Last-Modified')
};
diskCache.put(url, newRes);
memoryCache.put(url, newRes);
evictResource(); // 触发淘汰
return response.data;
}
return null;
}
// 视频流式播放缓存(示例:视频ID为video1,当前播放时间t=5秒)
function cacheVideoSegments(videoId, currentTime, networkType) {
const segmentDuration = 1; // 每段1秒
const cacheDuration = videoCacheDuration; // 根据网络类型动态调整
const startSegment = Math.floor(currentTime / segmentDuration);
const endSegment = startSegment + cacheDuration;
for (let i = startSegment; i <= endSegment; i++) {
const segmentUrl = getVideoSegmentUrl(videoId, i);
// 检查并缓存片段
if (!diskCache.has(segmentUrl)) {
fetchFromNetwork(segmentUrl, { headers: {} }).then(res => {
diskCache.put(segmentUrl, res.data);
});
}
// 内存缓存优先
memoryCache.put(segmentUrl, diskCache.get(segmentUrl));
}
// 淘汰远期片段(如i > endSegment + 2)
for (let i = endSegment + 3; i < totalSegments; i++) {
diskCache.remove(getVideoSegmentUrl(videoId, i));
}
}
// 淘汰机制(LRU)
function evictResource() {
// 内存LRU淘汰
let oldestKey = memoryCache.lruOldestKey();
memoryCache.remove(oldestKey);
// 磁盘同步删除
diskCache.remove(oldestKey);
}
5) 【面试口播版答案】
“面试官您好,针对客户端图片/视频资源缓存,我的核心设计是构建分层动态缓存体系,根据网络环境(Wi-Fi/4G)动态调整缓存大小与策略,并引入资源版本控制与精细化的淘汰机制。具体来说:首先,分层设计:内存缓存(RAM)用于高频访问的图片(如首页缩略图),大小设为10MB,通过LRU淘汰最久未访问的图片;磁盘缓存(SSD)用于视频等大文件,Wi-Fi下限制为5GB,4G下降至2GB,结合LRU与基于大小的淘汰(比如总空间不超过阈值时,淘汰最久未用的大文件)。其次,资源版本控制:通过请求头中的ETag(动态资源指纹)或Last-Modified(时间戳),客户端缓存资源后,下次请求时带上,服务器比较后若资源未更新则返回304,避免重复下载。然后,视频流式播放:按秒分段缓存(如视频每秒为一段),根据网络测速结果动态调整缓存片段数量——4G网络下,缓存当前播放片段及后续2-3秒片段;Wi-Fi下,缓存当前及后续5-10秒片段,支持断点续传。淘汰机制上,内存缓存用LRU维护访问时间,磁盘缓存通过空间限制+LRU,确保资源占用不超过预设阈值。实现时,请求资源先检查内存缓存(带版本校验),再检查磁盘缓存,网络请求成功后同步更新两者,并触发LRU淘汰旧资源。这样既能保证加载速度(本地缓存减少延迟),又能控制资源占用(4G下限制磁盘空间避免卡顿),同时支持视频流畅播放。”
6) 【追问清单】
7) 【常见坑/雷区】