深度解析某头条的一道面试题

2018年今日头条技术面试题解析与实战 简介:这份资料为2018年10月今日头条公司的内部技术面试题集,反映了当时互联网技术人才选拔的标准。题目内容覆盖大数据处理、编程语言、分布式系统等多个领域,涉及Java、Spark、Hadoop等关键技术。通过学习这些题目,求职者可以深入了解当时IT行业的技术趋势和关键知识点,为面试和提升专业技能做准备。 阅读详情

首先,某头条的文章量、用户量都是很大的,点击量那就更恐怖了。

请问,如果实时展现热门文章,比如近8小时点击量最大的文章前100名。

> 这个好办啊,redis一个sortedset搞定啊,score计数,key是文章ID,不就ok了么?

> 回答的不错,你可以走了!

要听清题目,说好的8小时动态时间窗口,计数是会过期的。还有,头条的量有这么小么,一个redis就搞定了?同学啊,我告诉你,文章的量你起码得估计个几十万,用户你得估计几个亿,点击量你至少得估计个1M/s吧。

数据接收

1M/s的点击并发量,肯定是需要分布式了。客户端可能会为了减轻服务器的压力而选择延迟合并点击请求进行批量发送。简单起见,这里就使用HTTP协议吧。我们先不考虑恶意用户刷点击的行为。

服务器肯定会有多台机器多进程部署来接受点击请求,接收到的请求在进行参数解析后,被发送到存储单元。为了减轻存储的压力,每个进程可能会使用小窗口聚合数据,每隔一小段时间将窗口内的数据聚合起来一起发给存储单元。

数据存储

点击数据是很重要的数据,用户的兴趣偏好就靠它了。这么大的点击数据如果全部用内存装的话,成本太高。所以别指望完全使用redis了。

拿kafka存是一个好办法,ZeroCopy机制并发量很高,数据持久化在磁盘里成本低。不过kafka的数据一般是有过期时间的,如果想完全记住用户的点击以便做长期的数据分析,少不了要使用hdfs了。

但是因为要做准实时统计,hdfs可不适合干这个,hdfs适合做离线统计的数据源。所以还得靠kafka接数据,然后消费者一边入hdfs,一边做实时统计。

实时统计可以使用spark stream、storm接受kafka的输入,也可以自己手写。

640?wx_fmt=png

分布式TopN算法

用户太多,用户表按用户ID哈希分成了1024张子表。用户表里有一个字段score,表示这个用户的积分数。现在我们要计算前100名积分最多的用户以及积分数,该怎么查询?

如果是单个表,一个SQL也就搞定了

select id, score from user order by score desc limit 100

如果是多个子表,你得在每个子表上都进行一次TopN查询,然后聚合结果再做一次TopN查询。下面是伪代码

candidates = []
for k in range(1024):
    # 每个表都取topn
    rows = select id, score from user_${k} order by score desc limit 100
    # 聚合结果
    candidates.extend(rows)
# 根据score倒排
candidates = sorted(candidates, key=lambda t: t[1], reverse=True)
# 再取topn
candidates[:100]

子表查询可以多线程并行,提高聚合效率。

滑动窗口

8小时的滑动窗口,意味着新的数据源源不断的进来,旧的数据时时刻刻在淘汰。严格来说,精准的8小时滑动窗口要求每条数据要严格的过期,差了1秒都不行,到点了就立即被淘汰。

精准的代价是我们要为每条点击记录都设置过期时间,过期时间本身也是需要存储的,而且过期策略还需要定时扫描时间堆来确认哪些记录过期了。量大的时候这些都是不容小嘘的负担。

但是在业务上来讲,排行版没有必要做到如此的精准,偏差个几分钟这都不是事。

业务上的折中给服务的资源优化带来了机遇。我们对时间片进行了切分,一分钟一个槽来进行计数。下面是伪代码

class HitSlot {
    long timestamp; # earlies timestamp
    map[int]int hits;  # post_id => hits
    void onHit(int postId, int hits) {
        this.hits[postId] += hits;
    }
}
class WindowSlots {
    HitSlot currentSlot;  # current active slots
    LinkedList<HitSlot> historySlots;  # history unactive slots
    map[int]int topHits; # topn posts
    void onHit(int postId, int hits) {  # 因为上游有合并点击,所以有了hits参数
        long ts = System.currentTimeMillis();
        if(this.currentSlot == null) { # 创建第一个槽
            this.currentSlot == new HitSlot(ts);
        } elif(ts - this.currentSlot.timestamp > 60 * 1000) {  # 创建下一个槽,一分钟一个槽
            this.historySlots.add(this.currentSlot);
            this.currentSlot = new HitSlot(ts);
        }
        this.currentSlot.onHit(postId, hits);
    }
    void onBeat() {  # 维护窗口,移除过期的槽,然后统计topn,30s~60s调用一次
        if(historySlots.isEmpty()) {
            return;
        }
        HitSlot slot = historySlots[0];
        long ts = System.currentTimeMillis();
        if(ts - slot.timestamp > 8 * 60 * 60 * 1000) {  # 过期了8小时,移掉第一个
            historySlots.remove(0);
            topHits = topn(aggregateSlots(historySlots));  # 计算topn的帖子
        }
    }
}

上面的代码代表着每个分布式子节点的逻辑,因为是伪代码,所以加锁问题就不细写了。

640?wx_fmt=png

定时任务

每个子节点都会有一个定时任务去负责维持统计窗口,过期失效的统计数据,计算局部的topn热帖。

现在每个子节点都有了各自的局部topn热帖,那么还需要一个主节点去汇总这些局部热点,然后计算去全局热帖。

主节点也没必要特别实时,定期从子节点拉取topn数据即可,也可以让字节点主动汇报。

class HotPostsAggregator {
    map[int]map[int]int localTopnPosts;  # nodeId => topn posts
    map[int]int globalTopnPosts;
    void onBeat() {
        // do aggregate
        // save globalTopnPosts to redis
    }
    void onLocalReport(int nodeId, map[int]int topnPosts) {
        // 子节点上报局部热帖
    }
}

散列

按照头条的文章至少几十万篇,如果每个子节点都要对所有的文章统计点击数,似乎也会占用不少内存,聚合和排序热帖也会有不少计算量。最好的想法是每个子节点只负责一部分文章的统计,这样可以明显节省计算资源。

我们将kafka的分区数设置为字节点的数量,这样每个节点负责消费一个分区的数据。在kafka生产端,对点击记录的帖子ID进行散列,保证相同文章ID的点击流进入相同的分区,最终流向同一个统计子节点。

640?wx_fmt=jpeg

消费者挂了

当机器增多时,节点挂掉的概率也会增大。硬件可能损坏,电源可能掉电,人为操作失误。如果没有做任何防范措施,当一个字节点挂掉时,该节点上8个小时时间窗口的统计数据将会丢失。该节点所管理的局部热点文章就丧失了进入全局热帖的机会。

这可能不会对产品和体验上带来很大的伤害,节点重启8小时之后也就完全恢复了。而且这8小时之内,丧失了部分文章的热点投票权也不会对整体业务带来巨大影响。

但是我们都希望系统可以更加完美一点不是么?当节点挂掉时,我们希望可以快速恢复状态,这也是可以做到的,难度也不是很大,不过是定时做一下checkpoint,将当前的状态持久化到本地文件或者数据库中。因为每个子节点管理的文章不会太多,所以需要序列化的内容也不会太大。当节点重启时,从持久化的checkpoint中将之前的状态恢复出来,然后继续进行消费和统计。

如果你使用的是spark-stream,它内置的checkpoint功能会让你实现备份和恢复会更加简单,更加安全。

如果你不想做checkpoint,办法还是有的,就是可能耗时旧一点。那就是对hdfs中的存储的所有的点击流数据进行一次mapreduce,将8小时窗口内的点击流的点击量统计出来,然后想办法导入到字节点进程中去。

这要求hdfs的数据也是散列存储的,和kafka对应,这样可以快速圈出需要统计的数据范围。也许会因为mapreduce本身会耗时一点时间,最终导致恢复的数据没有那么准确,不过这关系也不大,我们用这样粗糙的方法,能对得起那9.5成的数据已经做的很不错了。

点击去重

上面讲了一堆堆,代码敲了不少图画了不少,似乎很有道理。但是还有个重要的没提到,那就是点击去重。如果一个用户反复点击了很多次,那该如何计数比较合理。

一篇好的文章如果它不是太短的话,一般会吸引读者反复阅读很多次。这个计数如果完全去重了记为一次似乎也不太合理。但是如果是故意被人反复点击而被记了太多次明显也不好。那该如何选择呢?

首先要从客户端下手,客户端本身可以过滤一部分无效点击。同一篇文章在太短的时间内被当前用户反复点击,这个模式还是很好发现的。如果间隔时间比较长,那就是读者的回味点击,属于文章的正向反馈,应该记录下来。

客户端做好了,然后再从服务器端下手,服务器端下手就比较困难了。要探测用户的行为模式意味着要对用户的行为状态化,这样就会大量加重服务器的存储负担。

服务器还需要防止用户的防刷行为。如果缺失防刷控制,一个头条号可以通过这种漏洞来使得自己的文章非法获得大量点击,进入热门文章列表,打上热门标签,被海量的用户看到,就会获得较大的经济效益,即使这篇文章内容本身吸引力并不足够。

当用户发现这样差劲的内容也能上热门榜单时,无疑会对产品产生一定的质疑。如果这种行为泛滥开来,那就可能对产品造成比较致命的负面影响。

防刷是一门大型课题,本篇内容就不做详细讲解了,笔者在这方面也不是什么专家。简单点说放刷本质上就是提取恶意行为的特征。常见的策略就是同一篇文章被来自于同一个IP或者有限的几个IP的频繁点击请求,这时就可以使用封禁IP的招数来搞定。还可以使用用户反馈机制来识别非正常的热门内容,然后人工干预等。业界还有一些更高级的如机器学习深度学习等方法来防刷,这些读者都可以自行搜索研究。

640?wx_fmt=jpeg

阅读相关文章,关注公众号【码洞】

今日头条内部面试题.2018.10 目前已经入职一家不错的公司,其手头还有几家比较好的面试资料,与大家分享。 立即下载

相关推荐

SQL中Group分组获取Top N方法实现可首选row_number

统计每个城市的最新10个产品本文采用了游标方法/Count查询/cross apply方法/row_number方法等等对比不难发现Group获取Top N场景时,可以首选row_number,游标cursor其次,另外两个就基本不考虑了

数据结构基础23:TopN问题

前言:如果实时展现热门文章,比如近8小时点击量最大的文章前100名。如果是你来开发这个功能,你怎么做? 1、TopN排行榜问题描述: 在系统中,我们经常会遇到这样的需求:将大量(比如几十万、甚至上百万)的对象进行排序,然后只需要取出最Top的前N名作为排行榜的数据,这即是一个TopN算法。常见的解决方案有三种: (1)直接使用List的Sort方法进行处理。 (2)使用排序二叉树进行排序,...

何哥的博客 1711

基于ZYNQ7020芯片(黑金开发板AX7020)之AXI-FULL DDR的PL与PS交互操作。

在该工程中我们使用了PS端的串口接收功能,PS端串口接收和发送分别有一个64字节的FIFO,但是因为串口接收阈值设置为16,所以固定接收16个字节数据后才会发生中断。此测试工程得到以前知识的总结和各大网友的支持,只希望可以为学习的你更进一步,大家一起学习才是真的开心。加油,国产芯片之路。

landyjzlai的博客 3194

算法高级(25)-分布式TopN算法玄机

面试题:请问,某视频点播网站,希望实时展现热门视频,比如近8小时点击量最大的前100个视频。如果由你来开发这个功能,你怎么做? 一、思路分析 看到这样的一个问题,估计同学们会说,很简单呀,用Redis的SortedSet搞定啊,Score计数,Key是视频ID,不就OK了吗? 回答到这一步,只能说你回答的不错,下一位。too young too simple呀兄弟。 要听清楚题目,有8小时...

十步杀一人-千里不留行 1604

DSPACE仿真平台的使用

DSPACE仿真平台的使用 文章目录DSPACE仿真平台的使用1.ModelDesk新建项目2.MotionDesk引入项目3.ControlDesk引入项目4.项目整合运行 我们使用DSPACE仿真平台软件来模拟小汽车的自动驾驶。 总共需要用到DSPACE大类下的三个软件:ModelDesk、ControlDesk、MotionDesk。 1.ModelDesk新建项目 在桌面上点击ModelDesk图标,打开DSPACE—ModelDesk 选择 File 标签,侧边栏选择 New,点击 New A

qq_42582489的博客 7529

从Palantir到AI时代:Forward Deployed Engineer模式的深度解析

《从Palantir到AI时代:FDE模式的创新与挑战》摘要:Palantir开创的前置部署工程师(FDE)模式正在成为AI创业公司的标配。该模式通过现场工程师深入了解客户需求,填补产品与实际应用间的鸿沟,颠覆了传统SaaS规模化路径。核心优势在于将定制化服务转化为产品发现机制,特别适合高度异质化的AI市场。成功关键在于平衡定制与标准化,通过合同价值增长、产品杠杆效应等独特指标衡量成效。FDE人才需要兼具领域洞察力与快速原型能力。这一模式表明,在AI等新兴领域,深入客户现场可能比单纯追求技术突破更能创造商业

老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 4549

想法记录---实时计算的TopN的实现

TopN就是找出时间段内出现频率最高的n个 TopN的计算是个老生常谈的话题,比如微博的热搜,都是隔段时间就统计一次TopN 现在想做一个实时计算的TopN. 先说说离线计算的TopN,再说实时TopN ###离线TopN 离线TopN一般出现在大数据的应用场景,使用hadoop的map reduce,网上有很多案例 ###实时TopN 实时的计算,相比离线计算,会有如下问题 1.实时计算的数据不...

zhangsir的博客 9874

硬件手册——PT100精密测温电路

PT100精密测温电路 一、需求分析 根据题目要求为:测温范围为0-100℃、测温精度要求为±1℃。由于铂电阻具有精度高、性能可靠、稳定性好的特点,且铂电阻的电阻相对变化率与温度的关系曲线线性度最好,故选择铂电阻作为敏感元件。而在国标中,铂电阻有几种不同的标准,如PT100、PT1000。分别对应着0摄氏度下铂电阻的阻值为100R和1000R,由于需要考虑铂电阻的自发热问题,所以尽量选择阻值小的铂电阻,故选择PT100为最终型号。 二、电路设计 2.1 热电阻接法 热电阻测温电路有多种接法,其中三线制会导致

weixin_41655430的博客 5万+

今日头条一面:十道经典面试题解析

1.http请求头里,expire和cache-control字段含义,说说HTTP状态码 1.1 expire和cache-control字段含义 Cache-Control是HTTP/1.1的头字段,用来区分对缓存机制的支持情况,请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。主要有public、private、no-cache等值。 expires是http1.0的头字段,过期时间,如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求。 1.2 常见HTTP状态码

Java大将军的博客 792

基于强化学习控制策略的三相逆变器仿真

强化学习控制器的核心在于定义状态空间、动作空间、奖励函数以及选择合适的强化学习算法(例如DQN、DDPG等)。对于三相逆变器,状态可以是输出电压、电流等信息;动作则可能是调制指数的变化量;奖励函数则应鼓励快速准确地跟踪参考信号。定义状态空间和动作空间状态空间可以包括逆变器的输出电压、电流及其变化率等信息。动作空间则是控制器可执行的动作,例如PWM信号的调整幅度。matlab深色版本% 定义状态和动作空间维度numObs = 6;% 假设有六个状态变量(例如三相电压和电流)

amy_mhd的博客 137

直流无刷电机FOC控制算法 理论到实践 —— 实践

关于直流无刷电机FOC控制算法的理论章节,本人已经在前两章进行过详细说明,大家可以自行进行阅读,请务必了解过理论之后再来学习如何具体进行实现。直流无刷电机FOC控制算法 理论到实践 —— 理论(一)直流无刷电机FOC控制算法 理论到实践 —— 理论(二)本章节主要讨论采用MCU微控制器如何具体实现直流无刷电机的FOC控制。

爱出名的狗腿子 1万+

深度解析某头条的一道TopN面试题

首先,某头条的文章量、用户量都是很大的,点击量那就更恐怖了! 请问,如果实时展现热门文章,比如近8小时点击量最大的文章前100名。如果是你来开发这个功能,你怎么做? 这个好办啊,Redis一个SortedSet搞定啊,Score计数,Key是文章ID,不就OK了么? 回答的不错,你可以走了! 要听清题目,说好的8小时动态时间窗口,计数是会过期的。还有,头条的量有这么小么,一个Redis就搞定了?同...

cowbin2012的专栏 1万+

YOLO11训练中的批量大小(Batch Size)选择策略:分析Batch Size对训练速度、显存占用和模型性能的影响

在深度学习训练过程中,Batch Size(批量大小)是一个至关重要的超参数,它指的是单次迭代中用于更新模型权重的样本数量。简单来说,当我们训练神经网络时,不会一次性将所有数据喂给模型,而是将数据分成若干个小批次(batch),每个批次包含一定数量的样本,这个数量就是Batch Size。 Batch Size的核心作用在于平衡训练效率与模型性能。较小的Batch Size意味着每次更新权重时参考的信息较少,可能导致训练过程更加随机,但有时能带来更好的泛化能力;较大的Batch Size则能提供更稳定的梯

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 326

深度解析某头条的一道TopN面试题!

来源 | 公众号 | 码洞 | 作者 | 老钱首先,某头条的文章量、用户量都是很大的,点击量那就更恐怖了!请问,如果实时展现热门文章,比如近8小时点击量最大的文章前100...

Java后端技术 5795

BGP路由聚合:自动聚合和手动聚合

路由聚合是指将多条具体的路由合并为一条聚合路由,以减少路由表的条目数。这种技术通过只向对等体发送聚合后的路由,而不发送所有的具体路由,来减小路由表的规模。同时,被聚合的路由如果发生路由振荡,也不再对网络造成影响,从而提高了网络的稳定性。

网络技术联盟站 1221

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

京东-头条-百度面试题

清华本硕,硕士方向是自然语言处理,CCF A类论文一篇。目前拿到了京东,腾讯和搜狗的offer,因为腾讯和搜狗基本上没有问什么面试题,就两边聊了聊沟通一下,因此就不介绍面试经历了。 1 京东面试经历 面试的京东的商品推荐的算法岗,在北辰大厦(奥森旁边),面试难度总体来说比较简单。 (1) 到公司之后先做了一个小时的笔试题目,包括四个简答题和两个编程题,简答题主要是C语言相关的。 Map和S...

xiyue001的博客 1954

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

今日头条 前端面经

回馈一波~~今日头条,前端面经(三面全,offer已到手),19实习。 今日头条 2018.03.20 一面 一面问了好多问题,都是基础上很细节很钻的问题,平时不怎么遇到。 1.写一个深度拷贝 2.cdn原理 3.尾递归 4.状态码304 和 200 5.null == undefined 为什么 6.不同数据类型的值的比较,是怎么转换的,有什么规则 7.jit;jc...

javajavajava 1054

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

2024年安卓最新深入解析Android-Plugin-Framework,头条测试开发面试题

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。Android 基础知识点Java 基础知识点Android 源码相关分析常见的一些原理性问题。

2401_84563254的博客 937

一年半前端跳槽面试经验(头条、微信、shopee)

一年半前端跳槽面试经验(头条、微信、shopee) 在2019年末的时候,突然想搞点大事,思来想去,感觉只有跳槽是最刺激的。 由于我比较懒,不想换城市,所以这次只面试了头条、微信和 shopee。十分幸运,都拿到了 offer。接下来就简单的说下大家关心的面试题吧。问题的答案的话,之后有空我再补一下吧。 由于我之前的公司是有专门的重构工程师写 css 样式的,所以当面试官开始问 css 的时候,我都会跟面试官说我对 css 可能不是很熟,讲明原因。 头条 一面 1.position 有哪些属性 2.posi

weixin_47312141的博客 1087
上一篇: HTTP协议冷知识大全
下一篇: 水塘抽样与阶层固化
codehole_
博客等级 码龄7年 34粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值