今日头条android面试 android面试 好进吗

帐号:密码:下次自动登录{url:/nForum/slist.json?uid=guest&root=list-section}{url:/nForum/nlist.json?uid=guest&root=list-section}
贴数:1&分页:Lexie发信人: zhuxingyu (Lexie), 信区: Career_Upgrade
标&&题: 【今日头条】Android研发工程师
发信站: 水木社区 (Thu Oct 19 17:51:27 2017), 站内 && 【Android研发工程师】 && 职位描述: && 职位职责:&&&& 1、负责公司移动产品的研发,编写高质量的代码;&&&& 2、和产品经理配合,深度参与手机产品需求讨论,功能定义等;&&&& 3、设计良好的代码结构,不断迭代重构。&&&& 职位要求:&&&& 1、智能手机爱好者和使用者, 追求良好的用户体验;&&&& 2、热爱移动产品研发, 愿意在移动开发领域深入钻研, 并成为专家;&&&& 3、有良好的编程习惯, 代码结构清晰, 命名规范;&&&& 4、熟练掌握JAVA, 熟悉Android SDK, 熟悉Android的UI/网络/数据库框架;&&&& 5、一年以上Android开发经验, 能独立开发Android App;&&&& 6、对软件产品有强烈的责任心, 具备良好的沟通能力和优秀的团队协作能力。 && 薪资:20-40k
有意者请发送简历到
-- && ※ 来源:·水木社区 ·[FROM: 120.52.147.*]
文章数:1&分页:闲来无事,正看着百度新闻,突然灵感一闪,何不研究下一款新闻app,那就从今日头条开始吧。
1.1、轮廓分析
这里使用压缩软件打开,主要看lib目录及assets目录。
1.2、lib目录
lib目录主要是放一些库或jar包,打开后发现,只有一个armeabi目录,我们知道x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件,所以一个目录也是可以的,只是不能保证100%不crash。
* libandfix.so 阿里的一个热更新框架
* libcocklogic-1.1.3.so 阿里的一个推送
* libdaemon.so 内存泄漏检测
* libgif.so、libgifimage.so字面意思可知是图片显示库
* libimagepipeline.so facebook出品的fresco框架,这个框架使用率正在被Glide追赶,毕竟Glide是谷歌出的。
* libOcrEncryption.so 文字识别库
* libstatic-webp.so 支持主流webp格式图片,这个格式图片比jpg图片压缩率超高,几兆的图片都可能被压缩到几十k。
* libweibosdkcore.so 微博sdk
其他的不分析了,感兴趣可以自行百度。
1.3、assets目录
assets目录主要放置静态文件,且为只读权限,不能修改。
打开之后,发现大量的html、js、css文件,不愧是混合开发啊,一些静态文件都直接放assets里,加载的时候都不需要去网络读取。这里包含着jquery.js、rangy-core.js、TBAppLinkJsBridge.js(连接淘宝)、wpload.js、wpsave.js、android.js等。
第二步:抓包
由图可知,使用了httpdns服务,这种服务具有域名防劫持、精准调度的特性。尤其是阿里推出的httpdns号称0ms解析延迟。事实上,刚查了阿里的httpdns服务,ip就是203.107.1.1,确认其使用阿里的httpdns服务。
随便点击一条新闻试试,得到的地址是
可以看到这个网站并不带头部及底部的,看来只是为给今日头条或者其他第三方准备的,不信我在在该网站内随便点其他新闻
网址格式为
ttc和moddile不一样。这也说明头条是采用和第三方合作的方式解决文章的版权问题,自己管理着评论接口,另外我app上看到的新闻页面有些关键词被加了热点链接,可以知道今日头条通过js对网页处理过,或者是加工过。
其他地方很多都是通信,也没什么抓的。
第三步:反编译
有图可知共使用的服务有andfix、百度推送、极光推送、gson(我觉得fastjson更好用)、小米推送、华为推送、个信、autolay自动布局、友盟等等。
先分析下启用页SplashActivity
图中有个地方调了finish,看下条件:
isSplashCreateAbOn 没找到,不知道是干嘛的,估计写在so文件里了。
isTaskRoot判断是否在任务栈中的根Activity,即启动页面的第一个activity。
上面q、r方法代码如下(注释是猜测的意思):
private void q()
if (!com.ss.android.article.base.app.a.Q().cj()) {
ArticleBaseExtendManager.a().registDeviceManager(this);
private void r()
if (!this.D)
this.D = true;
this.E = ArticleBaseExtendManager.a().hasDetailInfo(this);
下面去看这个Manager方法:
package com.ss.android.article.base.feature.shrink.
import android.app.A
import android.content.C
import android.content.I
import mon.utility.L
import mon.utility.k;
import com.mon.shrink.extend.CoreExtendA
import com.mon.shrink.extend.CoreExtendSdkM
import java.util.HashM
import java.util.M
public class ArticleBaseExtendManager
extends CoreExtendSdkManager
private static CoreExtendSdkManager b = null;
public Map&String, CoreExtendAdapter& a = new HashMap();
private CoreExtendAdapter a(String paramString)
CoreExtendAdapter localCoreExtendAdapter2;
if (k.a(paramString))
localCoreExtendAdapter2 = null;
return localCoreExtendAdapter2;
localCoreExtendAdapter2 = (CoreExtendAdapter)this.a.get(paramString);
if (localCoreExtendAdapter2 != null) {
Object localObject2 = Class.forName(paramString).newInstance();
if (!(localObject2 instanceof CoreExtendAdapter)) {
localCoreExtendAdapter1 = (CoreExtendAdapter)localObject2;
catch (Throwable localThrowable1)
Object localObject1 = localThrowable1;
CoreExtendAdapter localCoreExtendAdapter1 = null;
localCoreExtendAdapter1 = null;
this.a.put(paramString, localCoreExtendAdapter1);
Logger.d("CoreExtendAdapter", "load ThirdExtendLibAdapter done: " + paramString);
return localCoreExtendAdapter1;
catch (Throwable localThrowable2) {}
Logger.w("CoreExtendAdapter", "load " + paramString + " has exception: " + localThrowable2);
return localCoreExtendAdapter1;
public static CoreExtendSdkManager a()
if (b == null) {}
if (b == null) {
b = new ArticleBaseExtendManager();
finally {}
public void baiduStatisticsEvent(Context paramContext, String paramString1, String paramString2)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.BaiduStatisticsAdapter");
if (localCoreExtendAdapter == null) {
localCoreExtendAdapter.baiduStatisticsEvent(paramContext, paramString1, paramString2);
public Intent getJumpIntent(Context paramContext)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.UgrReadApkAdapter");
if (localCoreExtendAdapter == null) {
return super.getJumpIntent(paramContext);
return localCoreExtendAdapter.getJumpIntent(paramContext);
public boolean hasDetailInfo(Context paramContext)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.UgrReadApkAdapter");
if (localCoreExtendAdapter == null) {
return super.hasDetailInfo(paramContext);
return localCoreExtendAdapter.hasDetailInfo(paramContext);
public void initBaiduStatistics(Context paramContext)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.BaiduStatisticsAdapter");
if (localCoreExtendAdapter == null) {
localCoreExtendAdapter.initBaiduStatistics(paramContext);
public void initGoogleAdSdk(Context paramContext)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.GoogleAdAdapter");
if (localCoreExtendAdapter == null) {
localCoreExtendAdapter.initGoogleAdSdk(paramContext);
public void registDeviceManager(Activity paramActivity)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.RegistDeviceManagerAda");
if (localCoreExtendAdapter == null) {
localCoreExtendAdapter.registDeviceManager(paramActivity);
public void startAppseStatistics(Context paramContext, String paramString)
CoreExtendAdapter localCoreExtendAdapter = a("com.ss.android.article.base.feature.shrink.extend.AppseeStatisticsAdapter");
if (localCoreExtendAdapter == null) {
localCoreExtendAdapter.startAppseStatistics(paramContext, paramString);
由上段代码可知:定义一个hash数组
public Map
protected Intent b()
Intent localI
if (this.F != null) {
localIntent = this.F;
return localI
localIntent = new Intent(this, MainActivity.class);
if (Build.VERSION.SDK_INT &= 11) {
localIntent.addFlags(32768);
} while (Build.VERSION.SDK_INT & 21);
localIntent.addFlags();
localIntent.addFlags();
return localI
再看看Main_Activity代码
public class MainActivity
extends com.ss.android.article.base.feature.main.a
private static Set&WeakReference&MainActivity&& V = new HashSet();
private WeakReference&MainActivity& W = new WeakReference(this);
public void onCreate(Bundle paramBundle)
com.bytedance.c.a.m(this);
k.a.a("MainActivity#onCreateStart");
Iterator localIterator = V.iterator();
while (localIterator.hasNext())
WeakReference localWeakReference = (WeakReference)localIterator.next();
if (localWeakReference != null)
Activity localActivity = (Activity)localWeakReference.get();
if ((localActivity != null) && (localActivity != this))
localActivity.finish();
super.onCreate(paramBundle);
catch (Throwable localThrowable) {}
k.a.a("MainActivity#onCreateEnd");
com.bytedance.c.a.n(this);
V.clear();
V.add(this.W);
protected void onDestroy()
super.onDestroy();
V.remove(this.W);
catch (Throwable localThrowable) {}
protected void onResume()
com.bytedance.c.a.o(this);
k.a.a("MainActivity#onResumeStart");
super.onResume();
k.a.a("MainActivity#onResumeEnd");
com.bytedance.c.a.p(this);
使用了弱引用WeakReference,其主要特点是:一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。这句话意思如果有activity页面没有被释放,在进入Main_Activity时都要执行finish的方法,解决后面多页面冲突的bug,其中,我们注意到private static Set &WeakReference&MainActivity&& V = new HashSet();的V是static修饰的,只会有一个对象,估计后面打开的每一个页面都会向v里增加activity。
瞎折腾一通,没多少技术含量,也许是瞎折腾。但是如果你需要去一家公司面试,先熟悉他所用的技术,提前做点功课、想好应对的策略,可以大大增加面试通过的胜算。
本文已收录于以下专栏:
相关文章推荐
在模仿中循序渐进,以程序员角度去看待每一个APP是如何实现的,它有什么优缺点,并从中提升自己。
       之前发现很多人在群里面、论坛上求网易新闻客户端的源码,之后我就去下了个网易新闻客户端和今...
起因看到众多大神纷纷有了自己的开源项目,于是自己琢磨着也想做一个开源项目来学习下,因为每次无聊必刷的app就是今日头条,评论简直比内容都精彩,所以我打算仿今日头条来练练手,期间也曾放弃过,也遇到很多坑...
高仿今日头条 --- 第一篇:(android高仿系列)今日头条
--新闻阅读器 (一)   
上次,已经完成了头部新闻分类栏目的拖动效果。
这篇文章是继续去完善APP 今日头条  这个新闻阅读器的...
距离上次发布(android高仿系列)今日头条
--新闻阅读器 (二)
相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下。完善的功能一个一个全部实现后,就放整个源码。开发的进度就是...
在模仿中循序渐进,以程序员角度去看待每一个APP是如何实现的,它有什么优缺点,并从中提升自己。
       之前发现很多人在群里面、论坛上求网易新闻客户端的源码,之后我就去下了个网易新闻客户端和今日...
从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据...
在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用...
Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘。
对这个对话框设置一个style效果:
一面(45min):
约了27号下午三点,还好只等了半个小时面试官就上线了,有的等了两个小时,面试官是一个微胖的中年人,说话特温柔,,,,,
1.ArrayList、LinkedList、Hash...
他的最新文章
讲师:汪剑
讲师:刘道宽
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 android 今日头条源码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信