51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

请设计一个客户端的图片/视频资源缓存策略,考虑不同网络环境(如4G/5G、Wi-Fi)下的加载速度和资源占用,并说明如何实现资源淘汰机制。

快手客户端开发工程师 📦 工程类难度:中等

答案

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) 【追问清单】

  • 问:网络环境从Wi-Fi切换到4G时,如何保证缓存一致性?
    回答要点:通过监听网络状态变化(如网络状态监听器),当网络从Wi-Fi切换到4G时,触发缓存策略调整,比如减少磁盘缓存大小(如从5GB降至2GB),优先加载内存缓存,避免4G下加载大视频导致卡顿,同时更新缓存策略中的淘汰阈值(如4G下LRU淘汰更频繁)。
  • 问:视频流式播放的缓存策略中,如何动态调整缓存大小?
    回答要点:根据用户网络速度(如通过测速API获取当前带宽)和设备存储空间(如检查可用空间),动态调整缓存的视频片段数量。例如,4G网络下,缓存当前及后续2-3秒片段;Wi-Fi下,缓存当前及后续5-10秒片段,提升播放流畅度。
  • 问:资源版本控制中,ETag和Last-Modified如何选择?
    回答要点:对于频繁更新的资源(如动态图片、实时数据),使用ETag(动态指纹),因为每次更新都会改变ETag;对于静态资源(如视频片段、静态图片),使用Last-Modified(时间戳),因为更新频率低,减少请求头大小。客户端缓存时记录版本信息,下次请求时带上,服务器比较后决定是否更新。
  • 问:内存缓存和磁盘缓存如何同步?
    回答要点:内存缓存和磁盘缓存通过LRU淘汰机制同步,当内存缓存淘汰资源时,同时从磁盘删除对应文件,避免磁盘空间浪费;网络请求成功后,同步更新两者,确保数据一致性。例如,内存缓存淘汰一个图片资源,磁盘缓存也删除该文件,下次请求时从网络重新下载。
  • 问:如何处理缓存击穿(如热门视频同时请求导致缓存失效)?
    回答要点:使用分布式缓存(如Redis)或本地缓存加锁机制,热门视频缓存时加互斥锁,避免多线程同时写入导致缓存失效,同时设置缓存预热策略,提前加载热门视频资源,减少缓存失效次数。

7) 【常见坑/雷区】

  • 忽略资源版本控制,导致资源更新后用户仍看到旧内容,影响体验。
  • 视频缓存策略简单,只缓存整个视频,未按片段分段,导致4G下加载时间长,播放卡顿。
  • 淘汰机制不具体,只说“淘汰旧资源”而不说明LRU或基于大小的算法,面试官会追问细节。
  • 内存与磁盘缓存不同步,导致内存有资源但磁盘无,或磁盘有旧资源,影响资源占用。
  • 网络环境适配不足,统一采用相同缓存策略,导致Wi-Fi下资源占用过大,4G下加载速度慢。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1