七、实时指标
- 每日日活实时统计
- 每日订单量实时统计
- 一小时内日活实时统计
- 一小时内订单数实时统计
- 一小时内交易额实时统计
- 一小时内广告点击实时统计
- 一小时内区域订单数统计
- 一小时内区域订单额统计
- 一小时内各品类销售 top3 商品统计
- 用户购买明细灵活分析(根据区域,性别,品类等)
八、写出分析最难的两个指标
面试官说现场手写你分析过最难的两个指标:
最好不要选择最难的,除非你能完全写出来,并且还得让面试官理解你做的指标的含义,下面选择容易理解但不算简单的指标:
1. 活跃用户指标
我们经常会算活跃用户,活跃用户是指至少连续 5 天登录账户的用户,返回的结果表按照 id 排序。
+----+-----------+ | 7 | Jonathan | +----+-----------+
思路:
- 去重:由于每个人可能一天可能不止登陆一次,需要去重
- 排序:对每个 ID 的登录日期排序
- 差值:计算登录日期与排序之间的差值,找到连续登陆的记录
- 连续登录天数计算:select id, count(*) group by id, 差值(伪代码)
- 取出登录 5 天以上的记录
- 通过表合并,取出 id 对应用户名
参考代码:
SELECT DISTINCT b.id, name FROM (SELECT id, login_date, DATE_SUB(login_date, ROW_NUMBER() OVER(PARTITION BY id ORDER BY login_date)) AS diff FROM(SELECT DISTINCT id, login_date FROM Logins) a) b INNER JOIN Accounts ac ON b.id = ac.id GROUP BY b.id, diff HAVING COUNT(b.id) >= 5
注意点:
- DATE_SUB 的应用:DATE_SUB (DATE, X),注意,X 为正数表示当前日期的前 X 天;
- 如何找连续日期:通过排序与登录日期之间的差值,因为排序连续,因此若登录日期连续,则差值一致;
- GROUP BY 和 HAVING 的应用:通过 id 和差值的 GROUP BY,用 COUNT 找到连续天数大于 5 天的 id,注意 COUNT 不是一定要出现在 SELECT 后,可以直接用在 HAVING 中
2. 用户留存率
首先用户留存率一般是面向新增用户的概念,是指某一天注册后的几天还是否活跃,是以每天为单位进行计算的。
一般收到的需求都是一个时间段内的新增用户的几天留存
select '日期', '注册用户数', '次日留存率', '2日留存率', '3日留存率', dim_date ,total_cnt ,concat_ws('% | ', cast(round(dif_1cnt*100/total_cnt, 2) as string), cast(dif_1cnt as string)) ,concat_ws('% | ', cast(round(dif_2cnt*100/total_cnt, 2) as string), cast(dif_2cnt as string)) ,concat_ws('% | ', cast(round(dif_3cnt*100/total_cnt, 2) as string), cast(dif_3cnt as string)) ,concat_ws('% | ', cast(round(dif_4cnt*100/total_cnt, 2) as string), cast(dif_4cnt as string)) from ( select p1.state dim_date ,p1.device_os ,count(distinct p1.user_id) total_cnt ,count(distinct if(datediff(p3.state,p1.state) = 1, p1.user_id, null)) dif_1cnt ,count(distinct if(datediff(p3.state,p1.state) = 2, p1.user_id, null)) dif_2cnt ,count(distinct if(datediff(p3.state,p1.state) = 3, p1.user_id, null)) dif_3cnt ,count(distinct if(datediff(p3.state,p1.state) = 4, p1.user_id, null)) dif_4cnt from ( select from_unixtime(unix_timestamp(cast(partition_date as string), 'yyyyMMdd'), 'yyyy-MM-dd') state, user_id from user_active_day where partition_date between date1 and date2 and user_is_new = 1 group by 1,2 )p1 --日新增用户名单(register_date,user_id) left outer join ( select from_unixtime(unix_timestamp(cast(partition_date as string), 'yyyyMMdd'), 'yyyy-MM-dd') state, user_id from active_users where partition_date between date1 and date2 group by 1,2 )p3 --期间活跃用户(active_date,user_id) on (p3.user_id = p1.user_id) group by 1,2 ) p4;
九、面试官问
自己说完项目之后面试官就开始发问了,注意接招:
1. 如何保证你写的 sql 正确性?
我一般是造一些特定的测试数据进行测试。
另外离线数据和实时数据分析的结果比较。
2. 测试数据哪来的?
一部分自己写 Java 程序自己造,一部分从生产环境上取一部分。
3. 测试环境什么样?
测试环境的配置是生产的一半
4. 测试之后如何上线?
上线的时候,将脚本打包,提交 git。先发邮件抄送经理和总监,运维。通过之后跟运维一 起上线。
5. 你做的项目工作流程是什么?
- 先与产品讨论,看报表的各个数据从哪些埋点中取
- 将业务逻辑过程设计好,与产品确定后开始开发
- 开发出报表 SQL 脚本,并且跑几天的历史数据,观察结果
- 将报表放入调度任务中,第二天给产品看结果。
- 周期性将表结果导出或是导入后台数据库,生成可视化报表
6. Hadoop 宕机?
- 如果 MR 造成系统宕机。此时要控制 Yarn 同时运行的任务数,和每个任务申请的最大内存。
调整参数:yarn.scheduler.maximum-allocation-mb
(单个任务可申请的最多物理内存量,默认是 8192MB)
- 如果写入文件过量造成 NameNode 宕机。那么调高 Kafka 的存储大小,控制从 Kafka 到 HDFS 的写入速度。高峰期的时候用 Kafka 进行缓存,高峰期过去数据同步会自动跟上。
7. 说下 Spark 数据倾斜及解决?
数据倾斜以为着某一个或者某几个 partition 的数据特别大,导致这几个 partition 上的计算需要耗费相当长的时间。
在 spark 中同一个应用程序划分成多个 stage,这些 stage 之间是串行执行的,而 一个 stage 里面的多个 task 是可以并行执行,task 数目由 partition 数目决定,如 果一个 partition 的数目特别大,那么导致这个 task 执行时间很长,导致接下来 的 stage 无法执行,从而导致整个 job 执行变慢。
避免数据倾斜,一般是要选用合适的 key,或者自己定义相关的 partitioner,通 过加盐或者哈希值来拆分这些 key,从而将这些数据分散到不同的 partition 去执行。
如下算子会导致 shuffle 操作,是导致数据倾斜可能发生的关键点所在:
groupByKey;reduceByKey;aggregaByKey;join;cogroup
8. 为什么 Kafka 不支持读写分离?
在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从 而实现的是一种主写主读的生产消费模型。 Kafka 并不支持主写从读,因为主写从读有 2 个很明显的缺点:
- 数据一致性问题:数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A 数据的值都为 X, 之后将主节点中 A 的值修改为 Y,那么在这个变更通知到从节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y,由此便产生了数据不一致的问题。
- 延时问题:类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程需要经历 网络 → 主节点内存 → 网络 → 从节点内存 这几个阶段,整个过程会耗费一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历 网络 → 主节点内存 → 主节点磁盘 → 网络 → 从节 点内存 → 从节点磁盘 这几个阶段。对延时敏感的应用而言,主写从读的功能并不太适用。
而 kafka 的主写主读的优点就很多了:
- 可以简化代码的实现逻辑,减少出错的可能;
- 将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控;
- 没有延时的影响;
- 在副本稳定的情况下,不会出现数据不一致的情况。
十、最后的面试小技巧
最后给大家说一点面试小技巧:
一般来说,面试你的人都不是一个很好对付的人。别看他彬彬有礼,看上去笑眯眯的,很和气的样子。但没准儿一肚子坏水。
有些人待人特别客气,说话还稍稍有点结巴的,更容易让人上当。
所以,牢记一点,面试的时候保持高度警觉,对方不经意问出来的问题,很可能是他最想知道的。
- 首先说话语速不要太快,有些人介绍自己时滔滔不绝,说话特快。其实这里面有个信息传递的问题,跟别人谈事情,语速太快,往往容易说错,对方接受起来也有问题。所以中等语速就可以了。
- 问到期望薪金的时候,最好的回答是不回答,留到下一次面试再谈。或者可以反问,公司对于这个岗位定的薪金标准是多少。
- 不要紧张,表现得自然些,要有礼貌,别忘记和主考人招呼,说句"早上好"等。
- 举止要大方,不可闪缩,要保持自信。待主考人邀请你才可礼貌地坐下,不要太随便或左顾右盼;切忌装出懒洋洋和满不在乎的样子。
- 微笑可以减轻你内心的不安,更可以令面试的气氛变得融洽愉快。
- 让主考人知道你珍惜这次面试的机会。当主考人说话时,要眼望对方,并留心倾听。
- 让主考人先打开话匣子。答问题要直接了当,无须太繁复,也不要单说"是"或"不是";否则,主考人会觉得你欠缺诚意。深入的谈话内容有助主考人对你作出确切的评估。
- 假如有不太明白主考人的问题,应该礼貌地请他重复。不懂得回答的问题,不妨坦白承认。含糊其辞或乱吹牛会导致面试的失败。
- 不要打断主考人的说话,被要求就相同的问题重复作答也不能表示不耐烦,更切忌与主考人争辩。
- 主考人可能问你一些与面试或者申请的职位完全无关的问题,例如时人时事,目的在进一步了解你的思想及见识。
- 紧记在适当时机带出自已的优点和特长。但切勿显得过份自信或浮夸。
- 准备一些与该机构和申请的工作有关的问题在面试结束之前提出。这样能表现伙的积极,亦可给主考人留下良好印象。
- 最后,问清楚多久才知道面试结果。不要忘记向主考人道谢及说声"再见"才离去。