当前位置:网站首页>字节跳动春招攻略:学长学姐笔经面经,还有出题人「锦囊」
字节跳动春招攻略:学长学姐笔经面经,还有出题人「锦囊」
2022-07-06 09:29:00 【字节跳动技术范儿】
正在参加春季校招的同学们,此刻可能是最紧张的了:
简历投出去了,什么时候才能收到笔试通知啊?
收到了笔试通知,最后两天还来得及做什么准备?
面试会问什么问题?怎么才能提升通过率、拿到更好的offer?
不妨先来听一听过来人的故事。
我们找到了通过校招入职字节跳动的算法、后端、客户端、前端、大数据、测试方向的6位技术同学,分享他们校招中遇到的难题和拿到offer的独家秘笈。
来一起看看他们是如何过关斩将,拿到字节跳动offer的吧。
图形算法offer收割机「Lucas」同学
Lucas,北大硕士,2018年秋招进入字节跳动,笔试满分选手,目前在图形图像的算法方面已经有了独当一面的能力。
毕业前的校招季,Lucas投递了字节跳动图形图像算法方向的岗位,在收割了数家国际大厂的算法offer后,因为看好抖音的发展、热爱这个产品,选择加入字节跳动。
Lucas的校招经验:
我那年的笔试时长大约3个小时,有6、7道题目,主要是编程题,题目都有一些固定的套路。
前两道大题难度跟学校里的考试差不多,整体大约是竞赛题里的简单水平。整套笔试试卷估计我的同学里班里前几名、或者实验室准备最充分的那一批人能全部答对。
关于笔试题目,可以看看网上的很多像搜索、动态规划、枚举等类型的题目,也不用练太多,主要是训练反应速度,这样就可以在短时间内反应过来如何解答一道题。
这也不是为了提升能力,就像高考前的模拟考试一样,主要是培养应试的感觉,提升一下写代码的速度,适应答题这种场景,做一些应试练习。毕竟,哪怕是让天才去高考,如果他不适应考试的话也不一定能考状元。
需要注意的是,笔试用的网站没有自动代码提示,而且平时写代码时,一些简单的数据结构只要去调用就好了,不熟悉可以查;笔试的时候是没法查的,所以需要熟悉一下比如STL库之类的内容。
针对后面的面试,我做了三方面准备:
1、我总结了自己过去的经历,以及在学校里做过的工作,因为面试官可能是其他领域的,所以需要组织好语言、用通俗易懂的方式简单介绍自己做了什么。
2、前两轮的技术面试考验你的技术能力,因此,像跨模态特征学习、机器翻译、场景分类、目标检测、GAN生成,姿态估计、语义分割,还有xgboost,svm,特征工程这些算法都要温习一下。
3、对公司业务做一些了解,才能更好地回答“为什么要来我们公司”这类问题。
面试流程很快,2天就走完了,第一天从中午到下午直接完成了4轮面试。
第一轮是技术面,还记得当时面试官问了我一个关于目标检测算法的问题,包括目标检测的发展历程,还有学术界最近的SOTA(最优水平方案),应该也是考察你对这个领域的熟悉程度吧,有没有迅速跟进最新技术的意识。
第二轮也是技术面,面试官抓住了一个重点的loss function(损失函数)让我讲了讲对它的理解,还有对计算机视觉算法各个主要领域的认识,另外我简历里的项目面试官也比较感兴趣。
第三轮就是业务负责人来面试了,会聊一些对业务的看法,未来业务发展、个人规划相关的事情。
后来,HR又安排我和另外一个技术Leader交流了一次。这位Leader对我之前做的东西不是很了解,他之前也不是这个领域的,能感觉到他提前准备了一些技术问题来问我,之后看了我做的开源项目的库,可能是看代码水平吧,最后也会聊一些所在部门的发展机遇。
Lucas的算法校招划重点:
考察维度 | 考察方法 |
智力、逻辑能力 | 算法题、数学题 |
基础知识 | 编程语言题、数据结构 |
专业领域知识 | 图像处理、机器学习、深度学习、大数据、图形渲染 |
软素质(沟通能力、应变能力、抗压能力) | 无定式、考察方法偏主观 |
后端方向的「Ezra」同学
Ezra就读于北航计算机专业,2020年正在读大三的他参加了字节跳动春季校招获得offer。
目前,Ezra在做商业化客户增长相关的开发工作。
Ezra的校招经验:
校招开始前,我重点复习了计算机网络 、操作系统、数据库和基础的语法知识和相关题目,也在牛客看了一些面经。
投递简历后很快就收到了笔试通知,笔试考了几道算法题,涉及到动态规划、递归、双指针等。我参加过竞赛,觉得题目难度一般,感觉身边50%的同学都能通过。
做题也是需要方法的,笔试开始之后,我会按照从易到难的顺序做题,如果碰到做不出来的题,我不会花太多时间在上面。每道题我都会把代码写完,有一些题目即使做得不完美,比如超出了题目中要求的运行时间,我也会先写下来。
笔试结束后不到一周,我就接到了HR的面试通知,当时第一天面了一轮,第二天面了两轮,很快就收到了offer。
前两轮技术面都是一些细节的知识点;最后一面问题更宏观,都是更大、更难、更系统的问题。面试过程中也需要手写代码。
Ezra划重点
1. 操作系统、计算机网络基础知识
- 线程和进程的区别
- 进程间通信方式
- 什么是死锁,死锁产生的原因
- 操作系统的几种进程调度策略
- 分段与分页
- OSI七层模型
- TCP/UDP区别
- TCP的三次握手,四次挥手
- HTTP中GET/POST请求
2. 语言相关——以Java为例
- HashMap、泛型、反射、线程池、几种锁机制等
- JVM相关,例如JVM内存模型、GC策略等
3. 数据结构与算法基础
- 动态规划、递归、排序、分治、贪心等
- 二叉树、哈希、链表、图
4. 后端框架基础
- SpringBoot、SSM、SpringCloud
5. MySQL
- 引擎
- 索引与底层数据结构
- 主从分离
- 慢查询的解决方案
6. Redis、MonogoDB等NoSQL存储引擎
- 以Redis为例,底层数据结构、常用命令、分布式部署、缓存穿透、缓存雪崩等
7. 其他中间件,例如RocketMQ
从量子计算转客户端的「Peter」同学
Peter参加字节跳动2019年的春招时,已经从学校毕业了。
武汉大学物理系本科毕业后,Peter去了QS排名世界第六的苏黎世联邦理工(ETH Zürich)读量子计算方向的硕士,学校没有固定的毕业时间,Peter修够了学分,拿到毕业证后就投递了字节跳动面向海外应届生的校招。
因为本科辅修了计算机,硕士期间因为量子计算领域的科研要求,Peter也几乎花了一半的时间在写代码。因此,当他准备在工业界寻求机会的时候,通过内推投递了字节跳动的客户端方向。
Peter的校招经验:
校招之前,像列表、数据结构和一些常见的算法等几个大方向都需要准备。
准备做题的话,刷题网站上有太多题,追求数量没什么收益。应当针对不同题型,多反思做过的题目,而不是仅仅获得一个答案。比如某类题型有多种解法,对每个解法要有深入的探索。至于编程题的语言,这反而不是特别重要。
我感觉字节跳动的笔试没有太奇技淫巧的题,基本都是基础算法相关中等难度的题。一个题目不懂就看下一个,没做出来也不用太在意。
笔试大概过了一两周吧,我就收到了面试通知。对于面试,我主要做了一些心态上的准备。
我当时找了身边在互联网公司工作的朋友来模拟面试,虽然模拟面试中的问题没用上,但是可以帮助我消解紧张感,面对一些自我介绍、职业规划之类的问题,也可以有条有理地说清楚。
我参加了3轮技术面和1轮HR面,面试流程超级快,每轮面试大概30~40分钟,两轮面试之间会间隔15~20分钟,最后的HR面是简单的电话面试。技术面试之后很快我就收到offer了。
一面的题目是最简单的,主要考察个人技术能力。面试官很nice,我当时突然很紧张,想不出解法,面试官应该是看出来了,稍微点拨了一下。这也帮助我后面的几轮面试调整了心态。所以遇到面试题目不会的时候,不要闷头苦想,即使觉得很难,也可以先说说自己的思路。
二三面的题目更难,很大程度上是在问个人的想法,看你这个人的可塑性。比如面试官问了我在用什么App、觉得这些App什么地方有吸引力,可能是考察有没有产品sense。另外会讨论个人职业规划和对公司的看法,比如为什么不继续读博、为什么选客户端、关注哪些公司等,也没有问诸如“如果上级和你意见不合怎么办”这种刁钻的问题。
Peter划重点:
1. 基础的算法和数据结构,每个都得深入一些,需要多考虑一些error handling和corner case
- Arrays and Strings
- Linked List
- Stack, Queues and Heap
- Tree and Graph, DFS and BFS
- Bit Manipulation
- 面向对象编程的一些设计
- Dynamic Programming
2. 尽量深入了解计算机网路,比如TCP/UCT, HTTP/HTTPS,三次握手和四次握手
3. 了解下操作系统的基本概念,进程和线程的区别,进程间如何通信
4. 需要对过往的项目比较了解,尤其是非CS出身的同学,面试官一般会根据同学的水平来调整面试难度,对于非CS同学来说更容易出彩的地方就是过往的经验。
前端开源贡献者「ZY」同学
ZY同学本科毕业于山东大学软件工程专业,一名GitHub活跃用户,是Vue.js、StateOfJS、State of CSS等开源项目的贡献者之一。
在互联网公司和媒体有过两段前端开发的实习经验后,2019年,ZY参加秋招进入字节跳动。
他目前在商业化团队做互动广告的前端开发,你在抖音里看到的那些AR/VR形式、以及可以用手势和点击来互动的广告,都有ZY同学的功劳。现在他的工作也更快捷,虽然校招时投递的是前端方向,但目前也会用Node.js写后端业务。
ZY的校招经验:
我在校招季之前集中复习了两个月。
计算机基础相关的内容主要复习了数据结构、操作系统、计算机网络。
前端相关的内容看了一下HTML基础,HTML5,CSS基础,CSS3,JavaScript基础(翻了两遍红宝书),JavaScript es6(阮一峰的教程),然后看了看Vue和React的相关知识,以及Node.js相关的知识还有框架(Express、Koa这些)。
后来参加笔试,字节跳动的笔试是4道编程题,第一道题大约是LeetCode上简单题目的水平,第二、三道应该是中等难度,第四道比较难,应该有LeetCode困难水平,整体还是很有挑战性的。
其实笔试当天最重要的有两个点:
第一,找一个网速好且没人打扰的环境,因为像字节跳动这种全是编程题的笔试,频繁被打断是很不利于分析题目的,思路很容易就被打断了。
第二,要诚信,别作弊。像什么多人共同写代码、装个虚拟机开网页啥的,会被系统判定为作弊。
一周之后我就收到了面试通知,当时真的是高强度面试,从早上9点到下午3点,一天走完3轮面试,其中二面和三面长达1个小时。
第一轮面试主要是问了一些前端的基础问题,主要是JavaScript基础,以及框架的实现原理,然后手写了一个数组乱序的算法题。
第二轮问的就很广了,先问了计算机基础知识,然后手写了一个归并排序的算法题,之后问了很多前端相关的问题,最后还做了一道海盗分金的智力题。
第三轮问的就不只是技术问题了,主要是围绕着简历上的项目,去聊了一下做这些项目的背景、实现的技术细节和带来的收益。
首先是一些基础问题,包括计算机相关基础知识,前端的基础知识等等,这部分没太多技巧可言,就是看你的基本功扎不扎实。
其次是手撕代码,这部分是需要一定的练习的,想无bug地解出一道题还是挺难的,面试做题其实挺吃熟练度的,如果你之前做过类似的题,那么在面试的时候就能比较顺利地写出来。
最后是项目经历相关,这部分因人而异,但是一定要做到对自己的项目了然于心才可以。不论是这个项目的背景,还是所用的技术点,又或者是最后的产出,都需要做到能够比较清楚地表达出来,这样才能让面试官对这个项目的全貌以及你的技术水平有清晰的了解。
来自ZY同学的前端校招划重点:
1、基础知识
1-1、操作系统
- 进程和线程的关系
- 进程调度
- 线程同步机制
- 死锁原理
- 内存管理
1-2、计算机网络
- 7层网络协议
- 网络层相关(IP地址、IPV4、IPV6、子网掩码)
- 传输层相关(TCP、UDP)
- DNS解析
- 应用层相关(HTTP、HTTPS)
1-3、数据结构
- 堆、栈
- 链表
- 跳表、散列
- 二叉、多叉树相关算法
- 图相关算法
2、前端知识
2-1、HTML
- 常用标签、语义化标签
- HTML标签属性相关
- HTML事件相关
- HTML5新增内容
2-2、CSS
- 盒模型
- 选择器、样式权重
- CSS常用属性(如:position)
- CSS常用布局(如:flex、grid)
- CSS动画相关(animation)
- CSS浮动相关(float)
- 移动端适配
- 响应式布局
- CSS3新增内容
2-3、JS
- JS变量类型相关
- 函数、类相关
- 闭包、作用域相关
- promise、async、await相关
- Array类型相关知识,及常见api
- Object类型相关知识,及常见api
- xhr、fetch相关
- DOM相关
- BOM相关
- 正则表达式
- ES6、ES7、ES2020新增内容
2-4、浏览器
- 浏览器中的进程与线程
- 浏览器渲染原理
- 浏览器中的Eventloop
- 浏览器存储相关(localstorage、sessionstorage)
2-5、Node.js
- Nodejs中的Eventloop
- 后端http框架相关知识(如:中间件概念、koa的洋葱模型)
2-6、框架
- React相关知识
- Vue相关知识
2-7、其他
- 打包工具的使用与配置(如webpack、snowpack、esbuild等)
- 前端性能优化
大数据工程师「Water」同学
Water来自上海大学,硕士期间做医疗与AI方向的研究,同时自己朝大数据方向发展,做过相关的实习工作。2019年秋天,他通过校园招聘拿到了字节跳动的大数据工程师的offer。
Water的校招经验:
我参加的是秋招,所以秋招前的整个暑假期间一直在准备。
一方面我会看一些校招攻略、题目集合、还有知识点的梳理,网络上有很多大家整理好的内容;另一方面我也会看一些网上公开的题目。
我那场笔试大约有3~4道编程题,难度在所有互联网公司校招笔试里算中等。主要是算法题,数据结构与链表、递归算法、二叉树之类的,大数据方向的笔试题还有一些稍微复杂的数据结构。
笔试开始后,我会先把每个题都扫一眼,判断自己能不能做出来、花多长时间才能做出来。
然后从最简单的题目开始,如果觉得能做出来就多花一点时间做,把能拿到的分拿到;如果感觉做不出来就跳过。最后我笔试的时候把所有题都做出来了,还剩下很多时间。
就这样很快就收到了面试通知,最多也就过了半个月吧。
准备面试当然也需要做题,每天差不多有半天以上的时间在做准备。另外,自我介绍和简历上做过的事情是一定要想好怎么说的。面试之前的一段时间就要放松心态了,不要纠结于个别一两个知识点。
我一共参加了3轮面试,前两轮面试主要是编程语言相关的内容,我记得有Java插件相关的问题,问了简历上写的擅长的框架相关的知识点,当然也要做题,手写算法题,整体上二面比一面问得更深入。
三面也做题了,当时统一用的是牛客的平台,差不多是中等难度的算法题,问到的相关框架知识,如果你熟悉这个领域一定都知道。
后来入职之后,面试官都成了我的Leader或同事。
Water的开源面经 (当然,并不是所有知识点都会考)
1、大数据方向校招考察最核心的还是计算机基础知识,其他几位同学都有列举,这里不赘述啦。
2、Hadoop
- HDFS架构
- Yarn架构
- MapReduce过程
- Yarn调度MapReduce
- HDFS写流程
- HDFS读流程
- HDFS创建一个文件的流程
- Hadoop 1.x 和Hadoop 2.x 的区别
- Hadoop 1.x的缺点
- Hadoop HA介绍
- Hadoop的常用配置文件有哪些,自己实际改过哪些?
- 小文件过多会有什么危害,如何避免?
- 启动Hadoop集群会分别启动哪些进程,各自的作用
- 讲一下环形缓冲区的概念
3、Hive
- Hive内部表和外部表的区别
- Hive中sort by / order by / cluster by / distribute by的区别
- Hive的metastore的三种模式
- Hive中join都有哪些
- Impala 和 hive 的查询有哪些区别
- Hive中大表join小表的优化方法
- Hive Sql 是怎样解析成MR job的?
- Hive UDF简单介绍
- SQL题: 按照学生科目分组, 取每个科目的TopN
- SQL题: 获取每个用户的前1/4次的数据
4、Spark
- 讲一下Spark 的运行架构
- Spark的shuffle介绍
- RDD有哪些特点
- 讲一下宽依赖和窄依赖
- Spark中的算子都有哪些
- RDD懒加载是什么意思
- Spark on yarn模式下的cluster模式和client模式有什么区别
- Spark的stage是如何划分的
- 什么是数据倾斜,怎样去处理数据倾斜
完整版可见GitHub:
https://github.com/CheckChe0803/BigData-Interview
测试校招达人「猫小爪」同学
猫小爪,陕西科技大学2020届软件工程专业本科生,负责过业务测试,业务+SDK自动化建设,目前在负责移动端专项的一些专项建设,如灰度、settings等。
2019年秋招中,猫小爪拿到了十余家互联网公司测试岗位的offer,最终入职字节跳动。
猫小爪的校招经验:
我参加的那一场笔试总共4个大题,整体比较偏算法,包括回溯算法、动态规划之类,会稍微有一点点难度。
我投递过的互联网公司题目都还蛮难的,如果做足了准备的话,我感觉班里成绩中上的同学都可以挑战一下。
我会先大致把每个题目都过一遍,判断每道题属于哪种题型、能不能解出来、题目中哪个点不清楚。
因为笔试时间有限,需要先预估一下每道题需要多长时间才能做出来,衡量一下付出的时间和得分,从ROI最高的一道题开始做。
其实笔试最重要的是放松心情,这样才能让自己的思路打开,看到题目就可以扩展出一些思路。这样,即使有些题目来不及写代码,也可以先把自己的思路写上去。
笔试之后3天我就收到了面试通知,1天就把3轮技术面+1轮HR面走完了。
一面问到的都是简历上提到的点,比如操作系统、数据结构、数据库、编程语言等等,都是基础知识。
二面也是问简历上的内容,但是会比第一轮面试的内容更深入,会问过去项目中的思路,也要现场做题。
三面更注重项目的思考,比如为什么要做这个项目、做项目过程中遇到了什么问题、用什么方式解决的、怎样找到的解决方案、从项目里得到了什么,整体是面试官从项目里发掘你内心深层次的思考。最后,当面试官问我还有什么想说的时候,我把前两轮面试总结了一下,补充了之前没有提到的一些点。后来发现三面面试官就是我入职之后的Leader。
最后的HR面主要就是问手头已有的offer,以及介绍公司的现状和特点。
我之前面过几家互联网公司,有了一定的面试经验积累,因此参加字节跳动面试时心态比较放松,思路也更开阔,面试官提的每个问题都答上来了。
猫小爪的测试攻略:
1. 语言篇(以Java为例)
- JavaSE基本语法,类与对象,I/O,深浅拷贝等;
- 熟练使用JCF,看过相应源码,熟悉实现逻辑,如:ArrayList,LinkedList,HashMap等;
- 熟悉常见设计模式,如:单例模式,多例模式,工厂设计模式,代理模式等;
- 熟悉Java多线程特性,如:线程同步,线程池的实现原理等;
- 熟悉JVM内存划分和垃圾回收算法,异常处理机制,反射等;
2. 数据结构/算法篇
- 熟悉常用的数据结构,链表,队列,栈,二叉树等;
- 熟悉常用的排序算法,快速排序,归并排序,堆排序等;
- 了解深度、广度优先搜索算法;
3. 操作系统篇
- 了解进程和线程的区别是什么、线程同步的方法有哪些;
- 了解什么是死锁,产生条件是什么、如何避免;
- 了解Linux的常用命令和Vim的使用;
4. 网络篇
- TCP-IP五层模型;
- http状态码有哪些,含义是;
- TCP三次握手,为什么不是2次或者4次呢;
- TCP/UDP的区别;
- http和https的区别;
- 从浏览器输入一个url,到返回数据,中间发生了什么;
- HTTP,TCP,IP,ARP 协议等的工作过程;
5. 数据库篇
- 数据库三大范式是什么;
- MySQL数据库引擎MyISAM和inmoDB的区别;
- 什么是视图、视图的使用场景有哪些;
- 事务4大特性;
- 什么是索引、索引的数据结构是什么;
- 数据库的乐观锁和悲观锁是什么;
- 还了解哪些数据库,这些数据库的优缺点是什么;
6. 项目篇
- 做该项目的原因是什么、项目做完收获了什么;
- 项目中某部分是怎么实现的呢,思路是什么;
- 做项目中遇到了什么问题,是怎么样解决的呢,方案选取为何不选择另一个,优劣是什么;
7. 测试篇
- 熟悉常用测试用例的编写方法,缺陷的状态和状态之间的扭转 ;
- 了解V模型,W模型等常见的测试模型、测试手段等;
- 了解测试管理工具个自动化测试工具;
- 了解自动化框架并可以其进行测试用例编写。
出题人说
另外,我们也找到了神秘的笔试出题人,为同学们提供了一些通关暗示:
- 题目更关注的是简单知识的融会贯通,而不是高深莫测的算法。
- 每个笔试题都会都一个或少数几个关键的考察点,这个考察点也许是某种数据结构,某种算法,或者是某种思维模式,但通常不会直白地给出这个考察点是什么,而是会给一个规定情境,或者讲一个小故事,需要候选人第一步做的就是脱掉题目的“马甲”,识别出考点。
- 判卷一般都是机器自动阅卷,编程题会以通过的cases占总cases的比例来判定分数。有些题目可能不止一种做法,针对不同规模的test cases,可以采用不同的策略去拿到分数。
最后,再为大家回顾一下字节跳动春招的技术笔试安排。
笔试集中安排在了7个场次,每场集中笔试都是星期日,均为线上进行。
场次 | 日期 | 时间(北京时间) |
第一场 | 3月7日 | 19:00-21:00 |
第二场 | 3月14日 | 10:00-12:00 |
第三场 | 3月21日 | 10:00-12:00 |
第四场 | 3月28日 | 19:00-21:00 |
第五场 | 4月11日 | 19:00-21:00 |
第六场 | 4月25日 | 10:00-12:00 |
第七场 | 5月9日 | 19:00-21:00 |
需要参加在线集中笔试的是投递研发类职位的同学(后端、算法、客户端、前端、测试/测开、大数据、研发工程师-质量保障),根据你投递简历的时间,需要参加笔试的同学会提前1~3个工作日收到笔试邀请。
当然,如果你的简历亮点无数,也有可能不需要参加笔试,直通面试。
最后,想要了解更多字节跳动校招笔面试干货/实习体验/团队部门信息,记得关注我们「字节跳动技术范儿」哦。
边栏推荐
- Restful style interface design
- Hbuilder x format shortcut key settings
- 视频压缩编码和音频压缩编码基本原理
- 图像处理一百题(1-10)
- Usage of insert() in vector
- Shell_ 07_ Functions and regular expressions
- How to generate six digit verification code
- Sublime text code formatting operation
- Basic principles of video compression coding and audio compression coding
- ~70 row high
猜你喜欢
第五章 Yarn资源调度器
Solve the problem that intel12 generation core CPU single thread only runs on small cores
~74 JD top navigation bar exercise
Redis standalone startup
姚班智班齐上阵,竞赛高手聚一堂,这是什么神仙编程大赛?
How to configure hosts when setting up Eureka
Shell_ 00_ First meeting shell
提交Spark应用的若干问题记录(sparklauncher with cluster deploy mode)
~73 other text styles
Fdog series (I): think about it. It's better to write a chat software. Then start with the imitation QQ registration page.
随机推荐
~71 abbreviation attribute of font
字节跳动多篇论文入选 CVPR 2021,精选干货都在这里了
~72 horizontal and vertical alignment of text
How to generate six digit verification code
LeetCode 1640. Can I connect to form an array
Error occurred during initialization of VM Could not reserve enough space for object heap
Solr standalone installation
Chapter 5 yarn resource scheduler
Spark's RDD (elastic distributed data set) returns a large result set
The concept of spark independent cluster worker and executor
ByteDance 2022 school recruitment R & D advance approval publicity meeting, students' top 10 issues
~82 style of table
Codeforces Round #771 (Div. 2)
LeetCode 1447. Simplest fraction
Shell_ 03_ environment variable
Gridhome, a static site generator that novices must know
Spark独立集群Worker和Executor的概念
我走過最迷的路,是字節跳動程序員的腦回路
~84 form supplement
JS encapsulates the method of array inversion -- Feng Hao's blog