字节跳动笔试真题
# 字节跳动笔试真题
# 🏢 公司简介
字节跳动是全球领先的移动互联网公司,笔试题目注重算法创新、系统性能和用户体验。
# 📝 题目特点
- 算法创新:考查对新颖算法问题的思考能力
- 性能优化:关注算法的效率和优化
- 实际应用:结合抖音、今日头条等产品场景
- 思维敏捷:题目变化多样,考查应变能力
# 🎯 2024年春招真题
# 题目1:抖音视频推荐算法 🟡
题目描述: 设计一个视频推荐算法,根据用户的观看历史、点赞记录和视频特征,推荐用户可能感兴趣的视频。
输入:
- 用户观看历史
- 用户点赞记录
- 视频特征矩阵
- 推荐数量k
输出:
- 推荐的k个视频ID
解题思路:
class Video {
int id;
String category;
Set<String> tags;
double popularity;
int duration;
public Video(int id, String category, Set<String> tags, double popularity, int duration) {
this.id = id;
this.category = category;
this.tags = tags;
this.popularity = popularity;
this.duration = duration;
}
}
class UserProfile {
Set<Integer> watchedVideos;
Set<Integer> likedVideos;
Map<String, Double> categoryPreference;
Map<String, Double> tagPreference;
public UserProfile() {
this.watchedVideos = new HashSet<>();
this.likedVideos = new HashSet<>();
this.categoryPreference = new HashMap<>();
this.tagPreference = new HashMap<>();
}
}
public List<Integer> recommendVideos(UserProfile user, List<Video> allVideos, int k) {
List<VideoScore> candidates = new ArrayList<>();
for (Video video : allVideos) {
if (!user.watchedVideos.contains(video.id)) {
double score = calculateScore(user, video);
candidates.add(new VideoScore(video.id, score));
}
}
return candidates.stream()
.sorted((a, b) -> Double.compare(b.score, a.score))
.limit(k)
.map(vs -> vs.videoId)
.collect(Collectors.toList());
}
private double calculateScore(UserProfile user, Video video) {
double score = 0.0;
// 类别偏好
score += user.categoryPreference.getOrDefault(video.category, 0.0) * 0.4;
// 标签偏好
for (String tag : video.tags) {
score += user.tagPreference.getOrDefault(tag, 0.0) * 0.3;
}
// 视频热度
score += video.popularity * 0.2;
// 时长偏好(假设用户喜欢中等时长的视频)
score += Math.exp(-Math.abs(video.duration - 60) / 30.0) * 0.1;
return score;
}
class VideoScore {
int videoId;
double score;
public VideoScore(int videoId, double score) {
this.videoId = videoId;
this.score = score;
}
}
# 题目2:今日头条热搜排行榜 🟠
题目描述: 实现一个实时热搜排行榜,根据关键词的搜索频次和时间衰减因子计算热度。
输入:
- 搜索记录流(关键词、时间戳)
- 时间窗口大小
- 衰减因子
输出:
- 实时热搜排行榜(前k个关键词)
解题思路:
class HotSearchRanking {
private Map<String, Double> keywordScores;
private Map<String, List<Long>> keywordTimestamps;
private double decayFactor;
private long timeWindow;
public HotSearchRanking(double decayFactor, long timeWindow) {
this.keywordScores = new HashMap<>();
this.keywordTimestamps = new HashMap<>();
this.decayFactor = decayFactor;
this.timeWindow = timeWindow;
}
public void addSearch(String keyword, long timestamp) {
// 清理过期数据
cleanExpiredData(timestamp);
// 添加新搜索记录
keywordTimestamps.computeIfAbsent(keyword, k -> new ArrayList<>()).add(timestamp);
// 更新热度分数
updateScore(keyword, timestamp);
}
public List<String> getTopK(int k, long currentTime) {
cleanExpiredData(currentTime);
return keywordScores.entrySet().stream()
.sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
.limit(k)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
private void updateScore(String keyword, long timestamp) {
List<Long> timestamps = keywordTimestamps.get(keyword);
double score = 0.0;
for (long ts : timestamps) {
double timeDiff = (timestamp - ts) / 1000.0; // 转换为秒
score += Math.exp(-decayFactor * timeDiff);
}
keywordScores.put(keyword, score);
}
private void cleanExpiredData(long currentTime) {
long expireTime = currentTime - timeWindow;
keywordTimestamps.entrySet().removeIf(entry -> {
List<Long> timestamps = entry.getValue();
timestamps.removeIf(ts -> ts < expireTime);
return timestamps.isEmpty();
});
keywordScores.entrySet().removeIf(entry ->
!keywordTimestamps.containsKey(entry.getKey()));
}
}
# 题目3:飞书文档协同编辑 🔴
题目描述: 设计一个文档协同编辑系统,支持多用户同时编辑,需要处理操作冲突和保证数据一致性。
输入:
- 用户操作序列(插入、删除、修改)
- 操作时间戳
- 用户ID
输出:
- 最终的文档内容
- 操作冲突解决方案
解题思路:
class Operation {
enum Type { INSERT, DELETE, MODIFY }
Type type;
int position;
String content;
long timestamp;
String userId;
public Operation(Type type, int position, String content, long timestamp, String userId) {
this.type = type;
this.position = position;
this.content = content;
this.timestamp = timestamp;
this.userId = userId;
}
}
class CollaborativeEditor {
private StringBuilder document;
private List<Operation> operationHistory;
private Map<String, Long> userVersions;
public CollaborativeEditor() {
this.document = new StringBuilder();
this.operationHistory = new ArrayList<>();
this.userVersions = new HashMap<>();
}
public synchronized String applyOperation(Operation op) {
// 检查操作是否有效
if (!isValidOperation(op)) {
return "Invalid operation";
}
// 转换操作位置(处理并发冲突)
Operation transformedOp = transformOperation(op);
// 应用操作
switch (transformedOp.type) {
case INSERT:
document.insert(transformedOp.position, transformedOp.content);
break;
case DELETE:
int endPos = Math.min(transformedOp.position + transformedOp.content.length(),
document.length());
document.delete(transformedOp.position, endPos);
break;
case MODIFY:
int modifyEnd = Math.min(transformedOp.position + transformedOp.content.length(),
document.length());
document.replace(transformedOp.position, modifyEnd, transformedOp.content);
break;
}
// 记录操作历史
operationHistory.add(transformedOp);
userVersions.put(op.userId, op.timestamp);
return document.toString();
}
private boolean isValidOperation(Operation op) {
return op.position >= 0 && op.position <= document.length();
}
private Operation transformOperation(Operation op) {
int adjustedPosition = op.position;
// 根据历史操作调整位置
for (Operation historyOp : operationHistory) {
if (historyOp.timestamp < op.timestamp &&
historyOp.position <= op.position) {
switch (historyOp.type) {
case INSERT:
adjustedPosition += historyOp.content.length();
break;
case DELETE:
adjustedPosition -= historyOp.content.length();
break;
}
}
}
return new Operation(op.type, Math.max(0, adjustedPosition),
op.content, op.timestamp, op.userId);
}
public String getDocument() {
return document.toString();
}
}
# 🔍 历年高频考点
# 算法类
- 滑动窗口(最大/最小值问题)
- 双指针技巧(快慢指针、左右指针)
- 分治算法(归并排序、快速选择)
- 贪心算法(区间调度、活动选择)
# 数据结构类
- 堆和优先队列
- 字典树(Trie)
- 并查集(Union-Find)
- 线段树和树状数组
# 系统设计类
- 分布式缓存
- 消息队列
- 负载均衡
- 数据一致性
# 💡 备考建议
- 算法思维:培养快速分析问题的能力
- 代码实现:注重代码的简洁性和效率
- 系统理解:了解大规模系统的设计原理
- 创新思考:敢于尝试新的解题思路
- 时间控制:提高编码速度和准确性