├── .gitignore ├── Activity ├── Activity Task和Process.md ├── App优雅退出.md ├── README.md ├── onCreate源码分析.md ├── onSaveInstanceState源码内核分析.md ├── 为什么service里面startActivity抛异常.md ├── 深入理解Activity启动流程.md ├── 深刻剖析activity启动模式-1.md ├── 深刻剖析activity启动模式-2.md └── 深刻剖析activity启动模式-3.md ├── Android ├── Android基础面试核心内容.md ├── Android视频教程.md ├── Android面试精华题目总结.md ├── Android面试重点.md ├── Android面试题-1.md ├── Android面试题-2.md ├── Android高级面试10大开源框架源码解析.md ├── BAT大咖助力全面升级Android面试.md ├── README.md ├── img │ ├── Android启动流程.png │ ├── activity_fragment_lifecycle.png │ ├── architucture.png │ ├── collection.png │ ├── fragment_lifecycle.png │ ├── framework.jpg │ ├── framework.png │ ├── hashmap.jpg │ ├── http.jpg │ ├── 启动流程.png │ ├── 系统启动流程图.png │ ├── 面试.jpg │ ├── 面试题1.jpg │ ├── 面试题2.jpg │ ├── 面试题3.jpg │ └── 面试题4.jpg ├── 平台架构.md └── 接口安全.md ├── HR ├── README.md ├── 人事面试宝典.md ├── 人事面试宝典一之自我介绍.md └── 人事面试宝典二之离职.md ├── Java ├── 115个Java面试题及回答.md ├── 66道经典的Java基础面试题集锦.md ├── J2SE基础面试核心内容.md ├── J2SE高级面试核心内容.md ├── Java面试题-1.md ├── Java面试题-2.md ├── Java高级软件工程师面试考纲.md ├── README.md ├── img │ ├── clone1.png │ ├── clone2.png │ ├── clone3.png │ ├── gc基本原理.png │ ├── java内存模型.jpg │ ├── jdbc.png │ ├── jvm1.png │ ├── jvm2.png │ ├── jvm3.png │ ├── jvm4.png │ ├── jvm5.png │ ├── jvm6.png │ ├── 斐波那契数列.png │ └── 随机排序.png ├── 数据库求差.md └── 深拷贝浅拷贝.md ├── README.md ├── SUMMARY.md ├── Service ├── Android面试题-Service.md ├── Android面试题-Service不死之身.md ├── IntentService源码分析.md └── README.md ├── assets ├── activity_start_flow.png ├── wechat.jpg ├── weixin.png ├── 支付宝.jpg ├── 腾讯.png ├── 腾讯2.jpg └── 腾讯3.jpg ├── book.json ├── 开发遇到的问题 ├── Context原理分析.md ├── README.md ├── ViewPager和Fragment使用过程中会遇到哪些问题.md ├── 手把手教你如何解决as jar包冲突.md ├── 机型适配之痛.md ├── 终极解决ViewPager.setCurrentItem中间页面过多解决方案.md ├── 解决字体适配.md ├── 软键盘顶出去解决方案.md └── 迭代开发的时候如何向前兼容新旧接口?.md ├── 性能优化 ├── Android应用UI性能分析.md ├── App应用启动分析与优化.md ├── README.md ├── 与IPC机制相关面试题.md ├── 与性能优化相关试题一.md ├── 与性能优化相关试题三.md ├── 与性能优化相关试题二.md └── 内存泄漏监测.md ├── 源码分析 ├── Android源码编译实现静默安装和静默偷拍.md ├── README.md ├── Volley源码剖析.md ├── img │ ├── 静默安装和静默偷拍-1.png │ ├── 静默安装和静默偷拍-10.png │ ├── 静默安装和静默偷拍-11.png │ ├── 静默安装和静默偷拍-12.png │ ├── 静默安装和静默偷拍-13.png │ ├── 静默安装和静默偷拍-14.png │ ├── 静默安装和静默偷拍-15.png │ ├── 静默安装和静默偷拍-16.png │ ├── 静默安装和静默偷拍-17.png │ ├── 静默安装和静默偷拍-18.png │ ├── 静默安装和静默偷拍-19.png │ ├── 静默安装和静默偷拍-2.png │ ├── 静默安装和静默偷拍-20.png │ ├── 静默安装和静默偷拍-21.png │ ├── 静默安装和静默偷拍-22.png │ ├── 静默安装和静默偷拍-3.png │ ├── 静默安装和静默偷拍-4.png │ ├── 静默安装和静默偷拍-5.png │ ├── 静默安装和静默偷拍-6.png │ ├── 静默安装和静默偷拍-7.png │ ├── 静默安装和静默偷拍-8.png │ └── 静默安装和静默偷拍-9.png ├── okhttp内核剖析.md └── 注解框架内部实现原理.md ├── 登陆注册 ├── Oauth的实现原理.md ├── README.md ├── Token的实际意义.md └── 微信扫码登录内部实现原理.md ├── 经验分享 ├── 2016年4月某公司面试题及面试流程.md ├── 2017届实习生招聘面经.md ├── Andorid-15k+的面试题.md ├── Android 暑期实习生面试经验谈.md ├── Android 曲折的求职之路.md ├── BAT无线工程师面试流程详细解析.md ├── README.md ├── 一个五年Android开发者百度、阿里、聚美、映客的面试心经.md ├── 一个程序员的血泪史.md ├── 互联网公司面试经验总结.md ├── 互联网巨头BAT3内部员工的真实状况.md ├── 史上最全 Android 面试资料集合.md ├── 国内一线互联网公司内部面试题库.md ├── 工作三年后,我选择离开腾讯.md ├── 我为什么离开锤子科技?.md ├── 我为什么要离开华为?.md ├── 扫清Android面试障碍.md ├── 技术硬碰硬—阳哥带你玩转上海Android招聘市场.md ├── 杭州找 Android 工作的点点滴滴.md ├── 给培训班出来的一点不成熟的小建议.md ├── 腾讯公司程序员面试题及答案详解.md ├── 阿里+百度+CVTE面经合集.md └── 面试心得与总结:BAT、网易、蘑菇街 .md ├── 网络编程 ├── Android客户端和服务端如何使用Token和Session.md ├── README.md ├── 推送原理.md ├── 简单阐述一下及时推送原理?.md └── 阐述一下对XMPP协议理解以及优缺点?.md └── 面试技巧 ├── README.md ├── 我在面试中最喜欢问开发者的问题,和回答思路.md ├── 程序员面试宝典.md └── 罗永浩新东方万字求职信.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf -------------------------------------------------------------------------------- /Activity/Activity Task和Process.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | - [深刻剖析activity启动模式(一)](http://www.jianshu.com/p/b33fd8c550bf) 13 | - [深刻剖析activity启动模式(二)](http://www.jianshu.com/p/e1ea9e542112) 14 | - [深刻剖析activity启动模式(三)](http://www.jianshu.com/p/d13e3d552d4b) 15 | - [Activity Task和Process之间的关系](http://www.jianshu.com/p/d13e3d552d4b) 16 | - [service里面startActivity抛异常?activity不会](http://www.jianshu.com/p/16e880ceb3a4) 17 | 18 | ### 与XMPP相关面试题 19 | 20 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 21 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 22 | 23 | ### 与性能优化相关面试题 24 | 25 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 26 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 27 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 28 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 29 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 30 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 31 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 32 | 33 | ### 与登录相关面试题 34 | 35 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 36 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 37 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 38 | 39 | ### 与开发相关面试题 40 | 41 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 42 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 43 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 44 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 45 | - [字体适配](http://www.jianshu.com/p/33d499170e25) 46 | - [软键盘顶出去解决方案](http://www.jianshu.com/p/640bac6f58ab)与人事相关面试题 47 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 48 | 49 | AMS提供了一个ArrayList mHistory来管理所有的activity,activity在AMS中的形式是ActivityRecord,task在AMS中的形式为TaskRecord,进程在AMS中的管理形式为ProcessRecord。如下图所示 50 | 51 | ![img](http://upload-images.jianshu.io/upload_images/4037105-1a0f2628f74ca65e?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 52 | 53 | 从图中我们可以看出如下几点规则: 54 | 55 | 1) 所有的ActivityRecord会被存储在mHistory管理; 56 | 57 | 2) 每个ActivityRecord会对应到一个TaskRecord,并且有着相同TaskRecord的ActivityRecord在mHistory中会处在连续的位置; 58 | 59 | 3) 同一个TaskRecord的Activity可能分别处于不同的进程中,每个Activity所处的进程跟task没有关系; 60 | 61 | Activity启动时ActivityManagerService会为其生成对应的ActivityRecord记录,并将其加入到回退栈(back stack)中,另外也会将ActivityRecord记录加入到某个Task中。请记住,ActivityRecord,backstack,Task都是ActivityManagerService的对象,由ActivityManagerService进程负责维护,而不是由应用进程维护。 62 | 63 | 在回退栈里属于同一个task的ActivityRecord会放在一起,也会形成栈的结构,也就是说后启动的Activity对应的ActivityRecord会放在task的栈顶 64 | 65 | 执行adb shell dumpsys activity命令,发现有以下输出: 66 | 67 | ``` 68 | Task id #30 69 | TaskRecord{7f2f34a #30 A=com.maweiqi.second U=0 sz=2} 70 | Intent { flg=0x10000000 cmp=com.open.android.task1/.SecondActivity } 71 | Hist #1: ActivityRecord{a0f9ded u0 com.open.android.task3/.OtherActivity t30} 72 | Intent { flg=0x10400000 cmp=com.open.android.task3/.OtherActivity } 73 | ProcessRecord{12090b5 27543:com.open.android.task3/u0a62} 74 | Hist #0: ActivityRecord{1048af6 u0 com.open.android.task1/.SecondActivity t30} 75 | Intent { flg=0x10000000 cmp=com.open.android.task1/.SecondActivity } 76 | ProcessRecord{5bc013e 26035:com.open.android.task1/u0a59} 77 | 78 | Task id #31 79 | TaskRecord{dce52bb #31 A=com.open.android.task3 U=0 sz=1} 80 | Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.open.android.task3/.MainActivity } 81 | Hist #0: ActivityRecord{f9e58c5 u0 com.open.android.task3/.MainActivity t31} 82 | Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.open.android.task3/.MainActivity } 83 | ProcessRecord{12090b5 27543:com.open.android.task3/u0a62} 84 | 85 | Task id #29 86 | TaskRecord{5b063d8 #29 A=com.open.android.task1 U=0 sz=1} 87 | Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.open.android.task1/.MainActivity } 88 | Hist #0: ActivityRecord{689947d u0 com.open.android.task1/.MainActivity t29} 89 | Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.open.android.task1/.MainActivity } 90 | ProcessRecord{5bc013e 26035:com.open.android.task1/u0a59} 91 | 92 | Running activities (most recent first): 93 | TaskRecord{7f2f34a #30 A=com.maweiqi.second U=0 sz=2} 94 | Run #3: ActivityRecord{a0f9ded u0 com.open.android.task3/.OtherActivity t30} 95 | TaskRecord{dce52bb #31 A=com.open.android.task3 U=0 sz=1} 96 | Run #2: ActivityRecord{f9e58c5 u0 com.open.android.task3/.MainActivity t31} 97 | TaskRecord{7f2f34a #30 A=com.maweiqi.second U=0 sz=2} 98 | Run #1: ActivityRecord{1048af6 u0 com.open.android.task1/.SecondActivity t30} 99 | TaskRecord{5b063d8 #29 A=com.open.android.task1 U=0 sz=1} 100 | Run #0: ActivityRecord{689947d u0 com.open.android.task1/.MainActivity t29} 101 | 102 | mResumedActivity: ActivityRecord{a0f9ded u0 com.open.android.task3/.OtherActivity t30} 103 | ``` 104 | 105 | 从图对应文字在对应adb输出,这几个基本概念大家估计就清楚了。 106 | 107 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 108 | - 微信公众号名称:Android干货程序员 109 | 110 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /Activity/README.md: -------------------------------------------------------------------------------- 1 | ## Activity相关面试题 2 | 3 | - [onSaveInstanceState源码内核分析](onSaveInstanceState源码内核分析.md) 4 | - [深刻剖析activity启动模式-1](深刻剖析activity启动模式-1.md) 5 | - [深刻剖析activity启动模式-2](深刻剖析activity启动模式-2.md) 6 | - [深刻剖析activity启动模式-3](深刻剖析activity启动模式-3.md) 7 | - [Activity Task和Process之间的关系](Activity Task和Process.md) 8 | - [为什么service里面startActivity抛异常](为什么service里面startActivity抛异常.md) 9 | - [App优雅退出](Android面试题-app优雅退出.md) 10 | - [onCreate源码分析](onCreate源码分析.md) -------------------------------------------------------------------------------- /Activity/onCreate源码分析.md: -------------------------------------------------------------------------------- 1 | Activity扮演了一个界面展示的角色,堪称四大组件之首,onCreate是Activity的执行入口,都不知道入口到底干了嘛,还学什么android,所以本文会从源码的角度对其进行分析。 2 | 3 | 熟悉源码的会发现,真正启动Activity的实现都在ActivityThread,前面的调用过程略过 4 | 5 | ActivityThread的方法performLaunchActivity中调用了Instrumentation类中的方法callActivityOnCreate方法,继而调用了TargetActivity中的onCreate方法。 6 | 7 | ```java 8 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 9 | ...... 10 | Activity activity = null; 11 | activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); 12 | ...... 13 | if (r.isPersistable()) { 14 | mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 15 | } else { 16 | mInstrumentation.callActivityOnCreate(activity, r.state); 17 | } 18 | ...... 19 | } 20 | ``` 21 | 22 | #### **源码可知:** 23 | 24 | 1)通过反射的机制创建的Activity 25 | 26 | 2)这里的mInstrumentation是类Instrumentation 27 | 28 | 3)Instrumentation类中的方法callActivityOnCreate方法源码如下: 29 | 30 | ```java 31 | public void callActivityOnCreate(Activity activity, Bundle icicle) { 32 | prePerformCreate(activity); 33 | activity.performCreate(icicle); 34 | postPerformCreate(activity); 35 | } 36 | ``` 37 | 38 | #### **源码可知:** 39 | 40 | 1)activity.performCreate(icicle),其中的方法是通过activity,这个activity,形如:Activity activity = 子Activity的对象 41 | 42 | 2)在Activity类中的方法performCreate(icicle),源码如下: 43 | 44 | ```java 45 | final void performCreate(Bundle icicle) { 46 | onCreate(icicle); 47 | mActivityTransitionState.readState(icicle); 48 | performCreateCommon(); 49 | } 50 | ``` 51 | 52 | #### **源码可知:** 53 | 54 | 1)原来onCreate的生命周期方法是在这里回调的 55 | 56 | 2)在performCreate方法中调用的onCreate方法是MainActivity中的onCreate方法,那么到此MainActivity中的方法onCreate方法中的参数Bundle savedInstanceState也就知道来源了,此时,MainActivity中的方法也就被调用了。 57 | 58 | 再次看MainActivity中的方法onCreate: 59 | 60 | ```java 61 | @Override 62 | protected void onCreate(Bundle savedInstanceState) { 63 | super.onCreate(savedInstanceState); 64 | 65 | setContentView(R.layout.activity_main); 66 | ``` 67 | 68 | super.onCreate(savedInstanceState),其实这条语句放在子类中的onCreate方法中的任何位置都可,问题只是super.onCreate(savedInstanceState)必须要被执行,所以,最好也就是放在第一行,看起来比较明确,至于为什么,参考[onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 69 | 至此onCreate源码分析完毕。 -------------------------------------------------------------------------------- /Activity/为什么service里面startActivity抛异常.md: -------------------------------------------------------------------------------- 1 | **Android面试题-源码分析为什么service里面startActivity抛异常?activity不会** 2 | 3 | 我们有时候需要在service里面启动activity,但是会发现报如下异常: 4 | 5 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8dd39209dfdb4961?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 6 | 7 | 必须添加FLAG_ACTIVITY_NEW_TASK这个标记就可以了,那么为什么在activity里面不需要呢?接下来通过从源码角度带大家分析。 8 | 9 | ### **启动activity有两种形式** 10 | 11 | 1)直接调用Context类的startActivity方法;这种方式启动的Activity没有Activity栈,因此不能以standard方式启动,必须加上FLAG_ACTIVITY_NEW_TASK这个Flag,服务就是通过Context调用。 12 | 13 | 2)调用被Activity类重载过的startActivity方法,通常在我们的Activity中直接调用这个方法就是这种形式; 14 | 15 | ### **Context.startActivity源码分析** 16 | 17 | 我们查看Context类的startActivity方法,发现这竟然是一个抽象类;查看Context的类继承关系图如下: 18 | 19 | ![img](http://upload-images.jianshu.io/upload_images/4037105-1a5f12db8f551acf?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 20 | 21 | 我们看到诸如Activity,Service等并没有直接继承Context,Activity继承了ContextThemeWrapper,Service而是继承了ContextWrapper; 22 | 23 | #### **现在从源码分析ContextWrapper的实现:** 24 | 25 | ```java 26 | @Override 27 | public void startActivity(Intent intent) { 28 | mBase.startActivity(intent); 29 | } 30 | ``` 31 | 32 | 这个mBase是什么呢?这里我先直接告诉你,它的真正实现是ContextImpl类;至于为什么,有一条思路:在任意mBase打一个断点就能看到实现。 33 | 34 | Context.startActivity最终使用了ContextImpl里面的方法,代码如下: 35 | 36 | ```java 37 | @Override 38 | public void startActivity(Intent intent, Bundle options) { 39 | warnIfCallingFromSystemProcess(); 40 | if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 41 | throw new AndroidRuntimeException( 42 | "Calling startActivity() from outside of an Activity " 43 | + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 44 | + " Is this really what you want?"); 45 | } 46 | mMainThread.getInstrumentation().execStartActivity( 47 | getOuterContext(), mMainThread.getApplicationThread(), null, 48 | (Activity) null, intent, -1, options); 49 | } 50 | ``` 51 | 52 | #### **源码分析:** 53 | 54 | 1)大家看看抛出来的异常是不是还是熟悉的味道。 55 | 56 | 2)通过判断可知当前的intent.getFlags是否带有FLAG_ACTIVITY_NEW_TASK这个标记,如果没有抛出异常,因为源码使用了&运算符,只有两个位都是1,结果才是1,所以可知service没有带FLAG_ACTIVITY_NEW_TASK标记,才抛出异常。 57 | 58 | 3)真正的startActivity使用了Instrumentation类的execStartActivity方法;继续跟踪: 59 | 60 | ```java 61 | public ActivityResult execStartActivity( 62 | Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) { 63 | ...... 64 | try { 65 | ...... 66 | int result = ActivityManagerNative.getDefault() 67 | .startActivity(whoThread, who.getBasePackageName(), intent, 68 | intent.resolveTypeIfNeeded(who.getContentResolver()), 69 | token, target != null ? target.mEmbeddedID : null, 70 | requestCode, 0, null, options); 71 | checkStartActivityResult(result, intent); 72 | } catch (RemoteException e) { 73 | throw new RuntimeException("Failure from system", e); 74 | } 75 | return null; 76 | ``` 77 | 78 | #### **源码分析:** 79 | 80 | 1)到这里我们发现真正调用的是ActivityManagerNative的startActivity方法; 81 | 82 | ### **Activity.startActivity源码分析** 83 | 84 | ```java 85 | @Override 86 | public void startActivity(Intent intent) { 87 | this.startActivity(intent, null); 88 | } 89 | ``` 90 | 91 | #### **源码可知:** 92 | 93 | 1)调用当前类的startActivity方法,代码如下: 94 | 95 | ```java 96 | @Override 97 | public void startActivity(Intent intent, @Nullable Bundle options) { 98 | if (options != null) { 99 | startActivityForResult(intent, -1, options); 100 | } else { 101 | // Note we want to go through this call for compatibility with 102 | // applications that may have overridden the method. 103 | startActivityForResult(intent, -1); 104 | } 105 | } 106 | ``` 107 | 108 | #### **源码可知** 109 | 110 | 1)调用了startActivityForResult 111 | 112 | ```java 113 | public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { 114 | ...... 115 | Instrumentation.ActivityResult ar = 116 | mInstrumentation.execStartActivity( 117 | this, mMainThread.getApplicationThread(), mToken, this, 118 | intent, requestCode, options); 119 | ...... 120 | ``` 121 | 122 | #### **源码可知** 123 | 124 | 1)可以看到,其实通过Activity和ContextImpl类启动Activity并无本质不同,他们都通过Instrumentation这个辅助类调用到了ActivityManagerNative的方法。 125 | 126 | 2)只是Activity不会去检查标记,所以并不会抛出异常。 127 | 128 | 至此源码分析完毕。 -------------------------------------------------------------------------------- /Activity/深入理解Activity启动流程.md: -------------------------------------------------------------------------------- 1 | > 原文链接:[Cloud Chou](http://weibo.com/muguachou). http://www.cloudchou.com/android/post-788.html 2 | 3 | ## 概述 4 | 5 | Android中启动某个Activity,将先启动Activity所在的应用。应用启动时会启动一个以应用包名为进程名的进程,该进程有一个主线程,叫ActivityThread,也叫做UI线程。 6 | 7 | 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究。 8 | 9 | - [深入理解Activity启动流程(二)--Activity启动相关类的类图](http://www.cloudchou.com/android/post-793.html) 10 | - [深入理解Activity启动流程(三)--Activity启动的详细流程1](http://www.cloudchou.com/android/post-805.html) 11 | - [深入理解Activity启动流程(三)--Activity启动的详细流程2](http://www.cloudchou.com/android/post-815.html) 12 | - [深入理解Activity启动流程(四)--Activity Task的调度算法](http://www.cloudchou.com/android/post-858.html) 13 | 14 | ## Activity启动时的概要交互流程 15 | 16 | 用户从Launcher程序点击应用图标可启动应用的入口Activity,Activity启动时需要多个进程之间的交互,Android系统中有一个zygote进程专用于孵化Android框架层和应用层程序的进程。还有一个system_server进程,该进程里运行了很多binder service,例如ActivityManagerService,PackageManagerService,WindowManagerService,这些binder service分别运行在不同的线程中,其中ActivityManagerService负责管理Activity栈,应用进程,task。 17 | 18 | Activity启动时的概要交互流程如下图如下所示(点击图片可看[大图](http://www.cloudchou.com/wp-content/uploads/2015/05/activity_start_flow.png)): 19 | 20 | ![activity_start_flow](../assets/activity_start_flow.png) 21 | 22 | 用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的入口Activity,ActivityManagerService发现这个应用还未启动,则会通知Zygote进程孵化出应用进程,然后在这个dalvik应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService保存应用进程的一个代理对象,这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法。 -------------------------------------------------------------------------------- /Android/Android视频教程.md: -------------------------------------------------------------------------------- 1 | ## Android视频教程 2 | 3 | - 零基础入门Android语法与界面 4 | - Kotlin系统入门与进阶 5 | - 从Java到Kotlin系列精讲 6 | - Kotlin打造完整电商APP 模块化+MVP+主流框架 7 | - Android强化:服务与通信之广播、服务、蓝牙 8 | - Gradle3.0自动化项目构建技术精讲+实战 9 | - React Native技术精讲与高质量上线APP开发 10 | - 双平台真实开发GitHub App React Native技术全面掌握 11 | - Android应用发展趋势必备武器 热修复与插件化 12 | - Android通用框架设计与完整电商APP开发 13 | - 全程MVP手把手 打造IM即时通讯Android APP 14 | - RxJava从源码到应用,移动端开发效率秒提速 15 | - Android开发—高级开发专题系列全套课程 16 | - BAT大咖助力 全面升级Android面试 17 | - Android高级面试 10大开源框架源码解析 18 | - BAT大厂APP架构演进实践与优化之路 19 | - Android架构师之路 网络层架构设计与实战 20 | - Android互动直播APP开发 21 | - 从零开发Android视频点播APP 22 | - 组件化封装思想实战Android App 23 | - 带领新手快速开发Android App 24 | - 快速开发轻量级App -------------------------------------------------------------------------------- /Android/Android面试精华题目总结.md: -------------------------------------------------------------------------------- 1 | > 原文链接:http://blog.csdn.net/lmj623565791/article/details/24015867/ 2 | 3 | 下面的题目都是楼主在[Android](http://lib.csdn.net/base/android)交流群大家面试时遇到的,如果大家有好的题目或者好的见解欢迎分享,楼主将长期维护此帖。 4 | 5 | ## 某公司高级面试题 6 | 7 | 1、详述Android系统架构,包括层与层之间调用、binder、jni、底层文件读写方法 8 | 9 | android源码之前分为四层,如下图: 10 | 11 | ![](img/framework.jpg) 12 | 13 | 新的android源码分为五层([平台架构](平台架构.md)),增加了HAL层,如下图: 14 | 15 | ![](img/framework.png) 16 | 17 | - Linux Kernel 18 | 19 | Linux内核,主要是一些硬件驱动和Binder驱动(IPC进程间通信) 20 | 21 | - 硬件抽象层 22 | 23 | Android系统的硬件抽象层(Hardware Abstract Layer,HAL)运行用户空间中,它向下屏蔽硬件驱动模块的实现细节,向上提供硬件访问服务。通过硬件抽象层,Android系统分两层来支持硬件设备,其中一层实现在用户空间中,另一层实现在内核空间中。传统的Linux系统把对硬件的支持完全实现在内核空间中,即把对硬件的支持完全实现在硬件驱动模块中。 24 | 25 | Android系统里封装内核驱动程序的接口层。对上层提供接口,屏蔽底层驱动实现细节. 26 | 27 | 本来Linux内核可以负责驱动接口定义和驱动实现,但是受限于GNU License(开源感染性),如果厂商选择驱动接口和实现都在内核空间完成,就必须开放自己的驱动源代码。这是不符合厂商利益的(驱动包含核心硬件参数,与其他厂家竞争的法宝)。所以Google将Linux内核中跟底层硬件操作相关的逻辑封装成HAL层接口,厂商基于接口去实现,不直接在内核空间实现驱动。因为Android系统遵循Apache License,不强制开源。 28 | 29 | - Libraries and Android Runtime 30 | 31 | 原生C/C++库,系统运行的核心库,Android运行时环境,包括核心库和dvm 32 | 33 | - Application FrameWork 框架层 34 | 35 | 提供的是Java API,主要是各种Manager,如WindowManager,ActivityManager等。 36 | 37 | 硬件访问服务通过硬件抽象层模块来为应用程序提供硬件读写操作。由于硬件抽象层模块是使用C++语言开发的,而应用程序框架层中的硬件访问服务是使用Java语言开发的,因此,硬件访问服务必须通过Java本地接口(Java Native Interface,JNI)来调用硬件抽象层模块的接口。 38 | 39 | 在Android应用程序框架层开发硬件访问服务的目的是为了让上层的Android应用程序能够访问对应的硬件设备。 40 | 41 | - Applications 应用层 42 | 43 | 我们使用的系统自带App或者自己安装的App都属于应用层 44 | 45 | 应用程序框架中的基于Java语言的Binder接口是通过JNI来调用基于C/C++语言的Binder运行库来为Java应用程序提供进程间通信服务的 46 | 47 | 2、描述自己的一个项目,要求画出结构图,UML图,详细描述项目种的技术点,技术难点以及解决方案 48 | 49 | 3、一道[算法](http://lib.csdn.net/base/datastructure) 50 | 51 | 4、谈谈自己项目管理的方法、对[敏捷,即原型开发](http://lib.csdn.net/base/agile)软件开发的理解 52 | 53 | ## 基础面试题 54 | 55 | **1. 请解释下在单线程模型中Message,Handler,MessageQueue,Looper之间的关系。** 56 | 57 | 拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()不断遍历MessageQueue,Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler , sendMessage到MessageQueue,Looper不断从MessageQueue中取出消息,回调handleMessage方法。 58 | 59 | **2. 如果有个100M大的文件,需要上传至服务器中,而服务器form表单最大只能上传2M,可以用什么方法。** 60 | 61 | 这个问题不是很明确我觉得,首先来说使用http协议上传数据,特别在android下,跟form没什么关系。传统的在web中,在form中写文件上传,其实浏览器所做的就是将我们的数据进行解析组装拼成字符串,以流的方式发送到服务器,且上传文件用的都是POST方式,POST方式对大小没什么限制。 62 | 63 | 回到题目,可以说假设每次真的只能上传2M,那么可能我们只能把文件截断,然后分别上传了。 64 | 65 | **3. 内存溢出和内存泄漏有什么区别?何时会产生内存泄漏?内存优化有哪些方法?** 66 | 67 | 内存溢出通俗理解就是软件(应用)运行需要的内存,超出了它可用的最大内存。 68 | 69 | 内存泄漏就是我们对某一内存空间的使用,使用完成后没有释放。 70 | 71 | 内存优化:Android中容易内存溢出的部分,就是图片的加载,我们可以使用图片的压缩加上使用LruCache缓存的目的来控制图片所能够使用的内存。 72 | 73 | 还有对于比较耗资源的对象及时的关闭,例如Database Conn , 各种传感器 , Service 等等。 74 | 75 | **4. AsyncTask使用在哪些场景?它的缺陷是什么?如何解决?** 76 | 77 | AsyncTask 运用的场景就是我们需要进行一些耗时的操作,耗时操作完成后更新主线程,或者在操作过程中对主线程的UI进行更新。 78 | 79 | 缺陷:AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,如果此时向线程提交任务,将会抛出RejectedExecutionException。 80 | 81 | 解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。 82 | 83 | **5. Activity用SharedPreferences保存数据,大小有木有限制?** 84 | 85 | 这个真心查不到 86 | 87 | Sp的底层是由xml实现的,操作Sp的过程就是xml的序列化和解析的过程.Xml是储存在磁盘上的,因此考虑到IO速度问题,sp不适宜频繁操作.同时序列化xml就是将内存中的数据写到xml文件中,由于dvm的内存是很有限的,因此单个sp文件不建议太大,具体多大是没有一个明确的要求的,但是我们知道DVM堆内存也就是16M,因此数据大小肯定不能超过这个数字,其实SP设置的目的就是为了保存用户的偏好和配置信息的,因此建议不要保存太多的数据 88 | 89 | **6. Activity间通过Intent传递数据大小有没有限制?** 90 | 91 | 貌似是40K。Intent貌似应该是1m,Intent携带数据太大是会报错,比如携带一张大图片是就会发生异常 92 | 93 | **7. assest文件夹里放文件,对于文件的大小有没有限制?** 94 | 95 | assets目录更像一个附录类型的目录,Android不会为这个目录中的文件生成ID并保存在R类当中,因此它与Android中的一些类和方法兼容度更低。 96 | 97 | 同时,由于你需要一个字符串路径来获取这个目录下的文件描述符,访问的速度会更慢。但是把一些文件放在这个目录下会使一些操作更加方便,比方说拷贝一个[数据库](http://lib.csdn.net/base/mysql)文件到系统内存中。要注意的是,你无法在Android XML文件中引用到assets目录下的文件,只能通过AssetManager来访问 98 | 99 | 这些文件。数据库文件和游戏数据等放在这个目录下是比较合适的。另外,网上关于assets和raw的资料都千篇一律了,因此关于这两者中单个文件 100 | 101 | 大小不能超过1M的**错误**描述也在传播,即如果读取超过1M的文件会报"Data exceeds UNCOMPRESS_DATA_MAX (1314625 vs 1048576)"的IOException,还引申出种种解决方案。个人认为不应该有这样的限制,为了验证这个说法写了个Demo,发现将近5M的压缩包在assets和raw中都能正常访问,因此在这里纠正一下,理论上只要打包不超过Android APK 50M大小的限制都是没有问题的。当然了,不排除是Android很早期的时候因为设备硬件原因aapt在编译的时候对这两个文件夹大小做出了限制,如果是这样,较新版的ADT应该不会出现这种情况。 102 | 103 | 来自:http://my.eoe.cn/futurexiong/archive/5350.html 104 | 105 | **8. 启动一个程序,可以主界面点击图标进入,也可以从一个程序中跳转过去,二者有什么区别?** 106 | 107 | 是因为启动程序(主界面也是一个app),发现了在这个程序中存在一个设置为``的activity,所以这个launcher会把icon提出来,放在主界面上。当用户点击icon的时候,发出一个Intent: 108 | 109 | ```java 110 | Intent intent = mActivity.getPackageManager().getLaunchIntentForPackage(packageName); 111 | mActivity.startActivity(intent); 112 | ``` 113 | 114 | 跳过去可以跳到任意允许的页面,如一个程序可以下载,那么真正下载的页面可能不是首页(也有可能是首页),这时还是构造一个Intent,startActivity.这个intent中的action可能有多种view,download都有可能。系统会根据第三方程序向系统注册的功能,为你的Intent选择可以打开的程序或者页面。所以唯一的一点不同的是从icon的点击启动的intent的action是相对单一的,从程序中跳转或者启动可能样式更多一些。本质是相同的。 115 | 116 | **9. 程序之间的亲和性的理解** 117 | 118 | - 默认情况下一个应用的所有Activity都是具有相同的affinity,都是从application中继承,application的affinity默认就是manifest的包名。 119 | - affinity对Activity来说,就像是身份证一样,可以告诉所在的Task,自己属于其中的一员。 120 | - 应用场合: 121 | - 根据affinity重新为Activity选择合适的宿主Task 122 | - 与allowTaskReparenting属性配合 123 | - 启动Activity使用Intent设置了FLAG_ACTIVITY_NEW_TASK标记 124 | 125 | **10. 同一个程序,但不同的Activity是否可以放在不同的Task任务栈中?** 126 | 127 | 可以放在不同的Task中。需要为不同的activity设置不同的affinity属性,启动activity的Intent需要包含FLAG_ACTIVITY_NEW_TASK标记。 128 | 129 | **11. 横竖屏切换时候Activity的生命周期。** 130 | 131 | - 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次 132 | - 设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次 133 | - 设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法 134 | 135 | **12. AIDL的全称是什么?如何工作?** 136 | 137 | 全称是:Android Interface Define Language 138 | 139 | 在Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢? 显然, [Java](http://lib.csdn.net/base/javase)中不允许跨进程内存共享. 140 | 141 | 因此传递对象, 只能把对象拆分成[操作系统](http://lib.csdn.net/base/operatingsystem)能理解的简单形式, 以达到跨界对象访问的目的. 在J2EE中,采用RMI的方式, 可以通过序列化传递对象. 在Android中, 则采用AIDL的方式. 理论上AIDL可以传递Bundle,实际上做起来却比较麻烦。 142 | 143 | AIDL(Android接口描述语言)是一种接口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象.AIDL的IPC的机制和COM或CORBA类似, 是基于接口的,但它是轻量级的。它使用代理类在客户端和实现层间传递值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相关类; 2. 调用aidl产生的class. 144 | 145 | AIDL的创建方法: 146 | 147 | AIDL语法很简单,可以用来声明一个带一个或多个方法的接口,也可以传递参数和返回值。 由于远程调用的需要, 这些参数和返回值并不是任何类型. 148 | 149 | 下面是些AIDL支持的数据类型: 150 | 151 | 1. 不需要import声明的简单Java编程语言类型(int,boolean等) 152 | 153 | 154 | 2. String, CharSequence不需要特殊声明 155 | 156 | 157 | 3. List, Map和Parcelables类型, 这些类型内所包含的数据成员也只能是简单数据类型, String等其他比支持的类型. 158 | 159 | (另外: 我没尝试Parcelables, 在Eclipse+ADT下编译不过, 或许以后会有所支持 160 | 161 | **13. dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念** 162 | 163 | Dvm的进程是dalivk虚拟机进程,每个android程序都运行在自己的进程里面,每个android程序系统都会给他分配一个单独的liunx uid(user id),每个dvm都是linux里面的一个进程.所以说这两个进程是一个进程. -------------------------------------------------------------------------------- /Android/Android面试题-1.md: -------------------------------------------------------------------------------- 1 | ![](img/面试题1.jpg) 2 | 3 | ![](img/面试题2.jpg) 4 | 5 | ![](img/面试题3.jpg) 6 | 7 | ![](img/面试题4.jpg) 8 | 9 | ### 整个面试题视频如下(持续更新中): 10 | 11 | #### 与IPC机制相关面试题 12 | 13 | - [1- Davik进程linux进程线程之间的区别](https://v.qq.com/x/page/a03916l1n7h.html) 14 | - [2- aidl实现进程间通信](https://v.qq.com/x/page/m0391pnoyl7.html) 15 | - [3- messenger实现进程间通信](https://v.qq.com/x/page/t0391b2gjm5.html) 16 | - [4- ContentProvider实现进程间通信](https://v.qq.com/x/page/v0391vx3ynb.html) 17 | 18 | #### 与性能优化相关试题 19 | 20 | - [5- 什么是内存泄漏](https://v.qq.com/x/page/n0391if5dtb.html) 21 | - [6- 什么是内存溢出](https://v.qq.com/x/page/q03917e4zk5.html) 22 | - [7- 什么情况会导致内存泄漏](https://v.qq.com/x/page/j03927ullcj.html) 23 | - [8- 避免程序的OOM异常](https://v.qq.com/x/page/w0392bn6wto.html) 24 | - [9- 线程池原理](https://v.qq.com/x/page/u0393izwfut.html) 25 | - [10- UI性能优化](https://v.qq.com/x/page/j0393ytx9ob.html) 26 | - [11- 内存优化之字符串优化](https://v.qq.com/x/page/k0393ataw3l.html) 27 | - [12- 常见内存优化方式](https://v.qq.com/x/page/j0393gm2p7j.html) 28 | - [13- 性能分析之hierarchyviewer使用](https://v.qq.com/x/page/y0393sa0jlp.html) 29 | - [14- 性能分析之Lint规范代码](https://v.qq.com/x/page/d039381wbas.html) 30 | - [15- 性能分析之规避内存抖动](https://v.qq.com/x/page/x0393gf7qp6.html) 31 | - [16- 性能分析之内存检测工具介绍](https://v.qq.com/x/page/e03933o0tp7.html) 32 | 33 | #### 与XMPP相关试题 34 | 35 | - [17- 什么是XMPP和XMPP的数据格式](https://v.qq.com/x/page/t0394w3zhoa.html) 36 | - [18- 及时聊天的展示形式](https://v.qq.com/x/page/k0394y5jo6d.html) 37 | - [19- TCP和UDP协议](https://v.qq.com/x/page/b0394lzj76e.html) 38 | - [20- 极光推送原理](https://v.qq.com/x/page/h0394a7zioh.html) 39 | - [21- XMPP的基本概念](https://v.qq.com/x/page/s0394k4p10i.html) 40 | - [22- 常见消息推送的解决方案](https://v.qq.com/x/page/h0394s3mc5k.html) 41 | 42 | #### 与登录相关试题 43 | 44 | - [23- 微信扫一扫登录内部实现原理](https://v.qq.com/x/page/u03952rbbkc.html) 45 | - [24- 腾讯QQ三方登录实现原理](https://v.qq.com/x/page/p03953hoam3.html) 46 | - [25- 登录为什么要使用Token](https://v.qq.com/x/page/c0395s3jd4f.html) 47 | 48 | #### 与开发相关试题 49 | 50 | - [26- 迭代开发的时候如何向前兼容新旧接口](https://v.qq.com/x/page/a0395pv28zm.html) 51 | - [27- 应用程序的开发流程](https://v.qq.com/x/page/v0395agrpdw.html) -------------------------------------------------------------------------------- /Android/BAT大咖助力全面升级Android面试.md: -------------------------------------------------------------------------------- 1 | ## BAT大咖助力,全面升级Android面试 2 | 3 | 安卓面试全新升级课程,已经帮助很多同学在短时间内拿到了满意的offer,作为Android开发求职路上快速赢取满意offer的必备课程,不管你是什么级别的工程师,都可以通过这门课程的学习,轻松快速搞定Android面试,赢取满意offer! 4 | 5 | 6 | 7 | ## 课程章节 8 | 9 | ### 第1章 课程介绍 10 | 11 | 本章带你了解面试过程中会遇到的问题,个人应该摆正的心态,以及面试官最为看重你的解决问题的思路。 12 | 13 | ### 第2章 一线互联网公司初中高Android开发工程师的技能要求 14 | 15 | 本章对一线互联网公司各个级别Android开发工程师的招聘需求进行深入分析,并带大家清晰完整的了解面试复习与准备思路,做到有的放矢,有侧重点的进行复习与准备。 16 | 17 | ### 第3章 Android基础相关面试问题 18 | 19 | 本章主要从Android的五大组件给大家讲解,讲解的思路主要通过一道道面试题的思路带大家逐题破解,以点带面来复习巩固android基础知识,并会在每道课程结尾处给大家总结补充一些知识点,主要讲解:Fragment 、Service 、Binder 、Activity、 BroadCast 、WebView安全漏洞、android6.0/7.0增加的新功能。... 20 | 21 | ### 第4章 异步消息处理机制相关面试问题 22 | 23 | Android中异步消息处理在面试中是一定会被问到的,在实战过程中也是非常重要的一个开发手段,我们会从handler、Asynctask、IntentService、HandlerThread给大家详细讲解,主要通过使用、源码机制来给大家深入分析异步消息处理机制。 24 | 25 | ### 第5章 View相关面试问题 26 | 27 | 本章主要从view的绘制、事件分发、listview、属性动画来给大家进行讲解,自定义控件在日常开发中是也是必不可少的,本章主旨就是能了解其中的原理,从而在面试中遇到同类问题能给出相应的思路。 28 | 29 | ### 第6章 Android项目构建相关面试问题 30 | 31 | 开发过程中项目的构建是很重要一环,也是检验你是不是一个合格的android开发工程师的标志,面试中也会经常问到,在这里我们主要通过Android的编译打包、Proguard混淆、git的使用、gradle、渠道包这五个部分给大家分析,带大家了解Android构建的全过程,从而轻松应对这类问题的各种面试与开发。... 32 | 33 | ### 第7章 开源框架相关面试问题 34 | 35 | 本章主要带大家分析现在热门的开源框架主要有网络框架:retrofit/okhttp/volley,图片加载框架fresco/gilde/uil,IOC框架:butterknife/dagger2,分析的思路是从使用到深入源码分析,开源框架可以说是一个高级工程师的试金石,如果对于以上框架很熟悉,并能画出流程图,会让面试官对于刮目相看。... 36 | 37 | ### 第8章 Android异常与性能优化相关面试问题 38 | 39 | 随着现在的android开发业务逻辑不断扩大,对于手机的性能也提出了很高的要求,所以一款app在性能上如果能区别其他app也将脱颖而出,同样如果候选人能对性能优化很熟悉,也将在面试中脱颖而出,本章主要从UI卡顿、内存管理、内存泄漏这几个角度带大家分析性能优化。... 40 | 41 | ### 第9章 热门前沿知识相关面试问题 42 | 43 | 现在Android发展越来越快,对于一些前沿的知识,在面试中我们也是需要做到了解,这章从Android的插件化、热更新、rxjava、进程保活,组件化,签名过程,应用沙盒等方面给大家讲解,主要想做到扩大大家的知识面,让面试官看到你对android的热爱。 44 | 45 | ### 第10章 Java高级技术点面试问题 46 | 47 | 在Android的面试中,面试官通常缺少不了会问一下Java高级技术,本章就会为大家讲解Java相关高级技术面试点,包括GC/回收算法/堆栈/、反射/编译时vs运行时、注解(结合android annotation库)、范型、线程池/并发编程、Socket、IO/NIO、集合框架、类加载器、异常、继承/组合/多态、引用类型/内存泄漏、java虚拟机/d... 48 | 49 | ### 第11章 设计模式相关面试问题 50 | 51 | 设计模式是高级开发者的必备知识,面试中也是经常被问到,本章将结合Android使用场景,讲解常用的设计模式,让大家既掌握Android下设计模式的使用,又可轻松应对面试中关于设计模式的面试问题。包括观察者模式、动态代理 、工厂、策略类、装饰、桥接、单例等常用设计模式。... 52 | 53 | ### 第12章 网络协议相关面试问题 54 | 55 | 网络编程无论在开发中还是在面试中都是非常重要的,在面试中尤其对网络协议问的比较多,本章将会对网络协议进行讲解,包括https/http、dns、tcp/ip以及加密算法。 56 | 57 | ### 第13章 算法相关面试问题 58 | 59 | 算法作为编程的重要部分,在BAT等大公司基本是必考项,本章将结合案例为大家讲解常用常考的算法面试问题,帮助大家提高算法能力的同时轻松应对算法相关的面试。 60 | 61 | ### 第14章 课程总结 62 | 63 | 本章主要总结面试过程的相关技术点。同时也将面试的内容做一个归纳总结,最后非常感谢大家的支持,课程中遇到任何问题都可以在问答区提问,我在那里等着大家,有问必答,也祝愿大家都能尽早的获得一份心仪的offer。 -------------------------------------------------------------------------------- /Android/README.md: -------------------------------------------------------------------------------- 1 | ## Android面试题 2 | 3 | - [Android基础面试核心内容](Android基础面试核心内容.md) 4 | - [Android面试精华题目总结](Android面试精华题目总结.md) 5 | - [Android面试题-1](Android面试题-1.md) 6 | - [Android面试题-2](Android面试题-2.md) 7 | - [Android面试重点](Android面试重点.md) 8 | - [接口安全](接口安全.md) -------------------------------------------------------------------------------- /Android/img/Android启动流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/Android启动流程.png -------------------------------------------------------------------------------- /Android/img/activity_fragment_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/activity_fragment_lifecycle.png -------------------------------------------------------------------------------- /Android/img/architucture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/architucture.png -------------------------------------------------------------------------------- /Android/img/collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/collection.png -------------------------------------------------------------------------------- /Android/img/fragment_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/fragment_lifecycle.png -------------------------------------------------------------------------------- /Android/img/framework.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/framework.jpg -------------------------------------------------------------------------------- /Android/img/framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/framework.png -------------------------------------------------------------------------------- /Android/img/hashmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/hashmap.jpg -------------------------------------------------------------------------------- /Android/img/http.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/http.jpg -------------------------------------------------------------------------------- /Android/img/启动流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/启动流程.png -------------------------------------------------------------------------------- /Android/img/系统启动流程图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/系统启动流程图.png -------------------------------------------------------------------------------- /Android/img/面试.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/面试.jpg -------------------------------------------------------------------------------- /Android/img/面试题1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/面试题1.jpg -------------------------------------------------------------------------------- /Android/img/面试题2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/面试题2.jpg -------------------------------------------------------------------------------- /Android/img/面试题3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/面试题3.jpg -------------------------------------------------------------------------------- /Android/img/面试题4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Android/img/面试题4.jpg -------------------------------------------------------------------------------- /Android/平台架构.md: -------------------------------------------------------------------------------- 1 | Android 是一种基于 Linux 的开放源代码软件栈,为广泛的设备和机型而创建。下图所示为 Android 平台的主要组件。 2 | 3 | ![图 1. Android 软件栈](img/framework.png) 4 | 5 | ## Linux 内核 6 | 7 | Android 平台的基础是 Linux 内核。例如,[Android Runtime (ART)](https://developer.android.google.cn/guide/platform/index.html#art) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。 8 | 9 | 使用 Linux 内核可让 Android 利用[主要安全功能](https://source.android.com/security/overview/kernel-security.html),并且允许设备制造商为著名的内核开发硬件驱动程序。 10 | 11 | ## 硬件抽象层 (HAL) 12 | 13 | [硬件抽象层 (HAL)](https://source.android.com/devices/index.html#Hardware%20Abstraction%20Layer) 提供标准界面,向更高级别的 [Java API 框架](https://developer.android.google.cn/guide/platform/index.html#api-framework)显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如[相机](https://source.android.com/devices/camera/index.html)或[蓝牙](https://source.android.com/devices/bluetooth.html)模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。 14 | 15 | ## Android Runtime 16 | 17 | 对于运行 Android 5.0(API 级别 21)或更高版本的设备,每个应用都在其自己的进程中运行,并且有其自己的 [Android Runtime (ART)](http://source.android.com/devices/tech/dalvik/index.html) 实例。ART 编写为通过执行 DEX 文件在低内存设备上运行多个虚拟机,DEX 文件是一种专为 Android 设计的字节码格式,经过优化,使用的内存很少。编译工具链(例如 [Jack](https://source.android.com/source/jack.html))将 Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。 18 | 19 | ART 的部分主要功能包括: 20 | 21 | - 预先 (AOT) 和即时 (JIT) 编译 22 | - 优化的垃圾回收 (GC) 23 | - 更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置监视点以监控特定字段 24 | 25 | 在 Android 版本 5.0(API 级别 21)之前,Dalvik 是 Android Runtime。如果您的应用在 ART 上运行效果很好,那么它应该也可在 Dalvik 上运行,但[反过来不一定](https://developer.android.google.cn/guide/platform/verifying-apps-art.html)。 26 | 27 | Android 还包含一套核心运行时库,可提供 Java API 框架使用的 Java 编程语言大部分功能,包括一些 [Java 8 语言功能](https://developer.android.google.cn/guide/platform/j8-jack.html)。 28 | 29 | ## 原生 C/C++ 库 30 | 31 | 许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。例如,您可以通过 Android 框架的 [Java OpenGL API](https://developer.android.google.cn/reference/android/opengl/package-summary.html) 访问 [OpenGL ES](https://developer.android.google.cn/guide/topics/graphics/opengl.html),以支持在应用中绘制和操作 2D 和 3D 图形。 32 | 33 | 如果开发的是需要 C 或 C++ 代码的应用,可以使用 [Android NDK](https://developer.android.google.cn/ndk/index.html) 直接从原生代码访问某些[原生平台库](https://developer.android.google.cn/ndk/guides/stable_apis.html)。 34 | 35 | ## Java API 框架 36 | 37 | 您可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务: 38 | 39 | - 丰富、可扩展的[视图系统](https://developer.android.google.cn/guide/topics/ui/overview.html),可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器 40 | - [资源管理器](https://developer.android.google.cn/guide/topics/resources/overview.html),用于访问非代码资源,例如本地化的字符串、图形和布局文件 41 | - [通知管理器](https://developer.android.google.cn/guide/topics/ui/notifiers/notifications.html),可让所有应用在状态栏中显示自定义提醒 42 | - [Activity 管理器](https://developer.android.google.cn/guide/components/activities.html),用于管理应用的生命周期,提供常见的[导航返回栈](https://developer.android.google.cn/guide/components/tasks-and-back-stack.html) 43 | - [内容提供程序](https://developer.android.google.cn/guide/topics/providers/content-providers.html),可让应用访问其他应用(例如“联系人”应用)中的数据或者共享其自己的数据 44 | 45 | 开发者可以完全访问 Android 系统应用使用的[框架 API](https://developer.android.google.cn/reference/packages.html)。 46 | 47 | ## 系统应用 48 | 49 | Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。 50 | 51 | 系统应用可用作用户的应用,以及提供开发者可从其自己的应用访问的主要功能。例如,如果您的应用要发短信,您无需自己构建该功能,可以改为调用已安装的短信应用向您指定的接收者发送消息。 -------------------------------------------------------------------------------- /Android/接口安全.md: -------------------------------------------------------------------------------- 1 | 保证接口安全一般分为两种,一个是防数据篡改,一个是防数据泄漏,防篡改使用摘要验证,防泄漏使用加密 2 | 3 | 4 | 5 | ## token 6 | 7 | token=5位随机数+时间戳 8 | 9 | aesEnctrypt(token) 10 | 11 | (1)验证时间和服务器时间不能超过3分。 12 | 13 | (2)同一个时间戳,随机数只能使用一次。 14 | 15 | ## 对称加密 16 | 17 | 把参数对称加密 aes 18 | 19 | ## 签名验证 20 | 21 | ras 22 | 23 | 调用方,要提供公钥,sign(通过双方定义好的[算法](http://lib.csdn.net/base/datastructure)把摘要和参数计算后的值) 24 | 25 | 我们把post过来的参数先解密,通过制定的算法算出sign 26 | 27 | 我们看我们算出sign与调用方传过来的sign是否一致,一致则可以进行业务处理,不一致返回签名失败。 28 | 29 | sign算法 30 | 31 | secretKey是双方定义的摘要 32 | 33 | params是参数的hashmap集合 34 | 35 | ```java 36 | byte[] data=Digest.getDigest(secretKey, params); 37 | 38 | public class Digest { 39 | 40 | public static byte[] getDigest(String secretKey, Map params) throws Exception{ 41 | 42 | Set keySet = params.keySet(); 43 | 44 | TreeSet sortSet = new TreeSet<>(); 45 | 46 | sortSet.addAll(keySet); 47 | 48 | String keyValueStr = ""; 49 | 50 | Iterator it = sortSet.iterator(); 51 | 52 | while(it.hasNext()){ 53 | 54 | String key = it.next(); 55 | 56 | String value = params.get(key); 57 | 58 | keyValueStr += key + value; 59 | 60 | } 61 | 62 | keyValueStr = keyValueStr + secretKey; 63 | 64 | MessageDigest md = MessageDigest.getInstance("SHA-1"); 65 | 66 | return md.digest(keyValueStr.getBytes("utf-8")); 67 | 68 | } 69 | 70 | } 71 | 72 | boolean b=RsaUtil.verify(data, sign, publicKeyString); 73 | ``` 74 | 75 | b=false 返回签名失败。 76 | 77 | 以下是rasutil 78 | 79 | ```java 80 | /** 81 | 82 | * 83 | 84 | */ 85 | 86 | package com.hlmedicals.app.util; 87 | 88 | import Java.io.UnsupportedEncodingException; 89 | 90 | import java.security.KeyFactory; 91 | 92 | import java.security.PrivateKey; 93 | 94 | import java.security.PublicKey; 95 | 96 | import java.security.spec.PKCS8EncodedKeySpec; 97 | 98 | import java.security.spec.X509EncodedKeySpec; 99 | 100 | import com.itextpdf.xmp.impl.Base64; 101 | 102 | /** 103 | 104 | * @author dell 105 | 106 | * 107 | 108 | */ 109 | 110 | public class RsaUtil { 111 | 112 | public static void main (String [] args){ 113 | 114 | try { 115 | 116 | byte[] privateKeyString= IConst.privateKeyString.getBytes("utf-8"); 117 | 118 | byte[] publicKeyString= IConst.publicKeyString.getBytes("utf-8"); 119 | 120 | String data1 = "testabc"; 121 | 122 | //siyao签名 123 | 124 | byte[] data=data1.getBytes("utf-8"); 125 | 126 | byte[] s = sign(data, privateKeyString); 127 | 128 | boolean b=verify(data,s,publicKeyString); 129 | 130 | System.out.println(b); 131 | 132 | } catch (Exception e) { 133 | 134 | // TODO Auto-generated catch block 135 | 136 | e.printStackTrace(); 137 | 138 | } 139 | 140 | } 141 | 142 | /** 143 | 144 | * 使用私钥对数据进行加密签名 145 | 146 | * @param data 数据 147 | 148 | * @param privateKeyString 私钥 149 | 150 | * @return 加密后的签名 151 | 152 | */ 153 | 154 | public static byte[] sign(byte[] data, byte[] privateKeyString) throws Exception { 155 | 156 | KeyFactory keyf = KeyFactory.getInstance("RSA"); 157 | 158 | PrivateKey privateKey = keyf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(privateKeyString))); 159 | 160 | java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA"); 161 | 162 | signet.initSign(privateKey); 163 | 164 | signet.update(data); 165 | 166 | byte[] signed = signet.sign(); 167 | 168 | return Base64.encode(signed); 169 | 170 | } 171 | 172 | /** 173 | 174 | * 使用公钥判断签名是否与数据匹配 175 | 176 | * @param data 数据 177 | 178 | * @param sign 签名 179 | 180 | * @param publicKeyString 公钥 181 | 182 | * @return 是否篡改了数据 183 | 184 | */ 185 | 186 | public static boolean verify(byte[] data, byte[] sign, byte[] publicKeyString) throws Exception { 187 | 188 | KeyFactory keyf = KeyFactory.getInstance("RSA"); 189 | 190 | PublicKey publicKey = keyf.generatePublic(new X509EncodedKeySpec(Base64.decode(publicKeyString))); 191 | 192 | java.security.Signature signet = java.security.Signature.getInstance("SHA1withRSA"); 193 | 194 | signet.initVerify(publicKey); 195 | 196 | signet.update(data); 197 | 198 | return signet.verify(Base64.decode(sign)); 199 | 200 | } 201 | 202 | } 203 | ``` 204 | 205 | 4.http 转成htts 206 | 207 | 5.后台登录要有验证码,没有验证码 ,系统会被爆破,验证码不能被多次使用。 208 | 209 | 我的项目登录成功后把验证码存在session里。要把session验证码设定为空就可以。 210 | 211 | 6.系统上传文件时候,应该上传白名单的文件类型,防止jsp、jspx在系统中执行导致系统崩掉。 212 | 213 | 214 | 215 | 在开发过程中,肯定会有和第三方或者app端的接口调用。在调用的时候,如何来保证非法链接或者恶意攻击呢? 216 | 217 | ## 签名 218 | 219 | 根据用户名或者用户id,结合用户的ip或者设备号,生成一个token。在请求后台,后台获取http的head中的token,校验是否合法(和[数据库](http://lib.csdn.net/base/mysql)或者[Redis](http://lib.csdn.net/base/redis)中记录的是否一致,在登录或者初始化的时候,存入数据库/redis) 220 | 221 | 在使用Base64方式的编码后,Token字符串还是有20多位,有的时候还是嫌它长了。由于GUID本身就有128bit,在要求有良好的可读性的前提下,很难进一步改进了。那我们如何产生更短的字符串呢?还有一种方式就是较少Token的长度,不用GUID,而采用一定长度的随机数,例如64bit,再用Base64编码表示: 222 | 223 | ``` 224 | var rnd = new Random(); 225 | 226 | var tokenData = userIp+userId; 227 | 228 | rnd.NextBytes(tokenData); 229 | 230 | var token = Convert.ToBase64String(tokenData).TrimEnd('='); 231 | ``` 232 | 233 | 由于这里只用了64bit,此时得到的字符串为Onh0h95n7nw的形式,长度要短一半。这样就方便携带多了。但是这种方式是没有唯一性保证的。不过用来作为身份认证的方式还是可以的(如网盘的提取码)。 234 | 235 | ## 加密 236 | 237 | 客户端和服务器都保存一个秘钥,每次传输都加密,服务端根据秘钥解密。 238 | 239 | 240 | 241 | 客户端: 242 | 243 | ​ 1、设置一个key(和服务器端相同) 244 | 245 | ​ 2、根据上述key对请求进行某种加密(加密必须是可逆的,以便服务器端解密) 246 | 247 | ​ 3、发送请求给服务器 248 | 249 | 服务器端: 250 | 251 | ​ 1、设置一个key 252 | 253 | ​ 2、根据上述的key对请求进行解密(校验成功就是「信任」的客户端发来的数据,否则拒绝响应) 254 | 255 | ​ 3、处理业务逻辑并产生结果 256 | 257 | ​ 4、将结果反馈给客户端 258 | 259 | ## 第三方支持 260 | 261 | 比如[spring](http://lib.csdn.net/base/javaee) security-oauth 262 | 263 | 有兴趣的,可以参考这篇帖子 264 | 265 | http://wwwcomy.iteye.com/blog/2230265 266 | 267 | 268 | 269 | 多数采用OAuth2,不过对于盗cookie没招,走HTTPS吧 270 | 271 | api进行token校验或者签名,另外对于防刷,要进行限流 272 | 273 | 274 | 275 | 题主要看你如何定义接口安全了,我们可以看看新浪微博,每天无数的爬虫在爬,他的接口安全么?一般意义上安全指的是传输过程中不被盗取,走https基本可以做到,至于有人拿到api文档一类的东西(app被反向),那怎么样也防不了 276 | 277 | 所以如同楼上 278 | 1.对IP进行过滤,频繁访问的进行限制。 279 | 2.使用token令牌进行验证,通过后进行业务逻辑。 280 | 3.不对参数过渡暴露,传输的文本根据业务级别进行加密。 281 | 282 | 没有绝对的安全,题主可以看看微信开发者文档,看看他们的接口是怎么设计的 283 | 284 | 285 | 286 | 题主要看你如何定义接口安全了,我们可以看看新浪微博,每天无数的爬虫在爬,他的接口安全么?一般意义上安全指的是传输过程中不被盗取,走https基本可以做到,至于有人拿到api文档一类的东西(app被反向),那怎么样也防不了 287 | 288 | 所以如同楼上 289 | 1.对IP进行过滤,频繁访问的进行限制。 290 | 2.使用token令牌进行验证,通过后进行业务逻辑。 291 | 3.不对参数过渡暴露,传输的文本根据业务级别进行加密。 292 | 293 | 没有绝对的安全,题主可以看看微信开发者文档,看看他们的接口是怎么设计的 -------------------------------------------------------------------------------- /HR/README.md: -------------------------------------------------------------------------------- 1 | ## 人事面 2 | 3 | - [人事面试宝典一之自我介绍](人事面试宝典一之自我介绍.md) 4 | - [人事面试宝典二之离职](人事面试宝典二之离职.md) 5 | - [人事面试宝典](人事面试宝典.md) -------------------------------------------------------------------------------- /HR/人事面试宝典一之自我介绍.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | 可别小瞧人事面试时的各个介绍环节 46 | 47 | #### 1. 请你自我介绍一下你自己? 48 | 49 | 回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信。企业很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句“谢谢”。企业喜欢有礼貌的求职者。 50 | 51 | #### 2. 你觉得你个性上最大的优点是什么? 52 | 53 | 回答提示:沉着冷静、条理清楚、立场坚定、顽强向上。 54 | 乐于助人和关心他人、适应能力和幽默感、乐观和友爱。 55 | 56 | #### 3. 说说你最大的缺点? 57 | 58 | 回答提示:这个问题企业问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业肯定不会录用你。绝对不要自作聪明地回答“我最大的缺点是过于追求完美”,有的人以为这样回答会显得自己比较出色,但事实上,他已经岌芨可危了。企业喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分。企业喜欢聪明的求职者。 59 | 60 | #### 4. 你对加班的看法? 61 | 62 | 回答提示:实际上好多公司问这个问题,并不证明一定要加班。 只是想测试你是否愿意为公司奉献。 63 | 回答样本:如果是工作需要我会义不容辞加班。我现在单身,没有任何家庭负担,可以全身心的投入工作。但同时,我也会提高工作效率,减少不必要的加班 64 | 65 | #### 5. 你对薪资的要求? 66 | 67 | 回 答提示:如果你对薪酬的要求太低,那显然贬低自己的能力;如果你对薪酬的要求太高,那又会显得你分量过重,公司受用不起。一些雇主通常都事先对求聘的职位定下开支预算,因而他们第一次提出的价钱往往是他们所能给予的最高价钱。他们问你只不过想证实一下这笔钱是否足以引起你对该工作的兴趣 。 68 | 69 | 回答样本一:“我对工资没有硬性要求。我相信贵公司在处理我的问题上会友善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多 70 | 71 | 回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训。而且我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标准的水平,给我合理的薪水。 72 | 73 | 回答样本三:如果你必须自己说出具体数目,请不要说一个宽泛的范围,那样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。 74 | 75 | #### 6. 除了本公司外,还应聘了哪些公司? 76 | 77 | 回答提示:很奇怪,这是相当多公司会问的问题,其用意是要概略知道应徵者的求职志向,所以这并非绝对是负面答案,就算不便说出公司名称,也应回答“销售同种产品的公司”,如果应聘的其他公司是不同业界,容易让人产生无法信任的感觉。 78 | 79 | #### 7. 你还有什么问题要问吗? 80 | 81 | 回答提示:企业的这个问题看上去可有可无,其实很关键,企业不喜欢说“没有问题”的人,因为其很注重员工的个性和创新能力。企业不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?企业将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。 82 | 83 | > 总结一点:把命卖给公司,最后祝大家五一节快乐。 84 | 85 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 86 | 87 | 微信公众号名称:Android干货程序员 88 | 89 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /HR/人事面试宝典二之离职.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | #### 为什么要离职? 46 | 47 | 回答提示: 48 | 49 | ①回答这个问题时一定要小心,就算在前一个工作受到再大的委屈,对公司有多少的怨言,都千万不要表现出来,尤其要避免对公司本身主管的批评,避免面试官的负面情绪及印象;建议此时最好的回答方式是将问题归咎在自己身上,例如觉得工作没有学习发展的空间,自己想在面试工作的相关产业中多加学习,或是前一份工作与自己的生涯规划不合等等,回答的答案最好是积极正面的。 50 | 51 | ②我希望能获得一份更好的工作,如果机会来临,我会抓住;我觉得目前的工作,已经达到顶峰,即沒有升迁机会。 52 | 53 | #### 您在前一家公司的离职原因是什么? 54 | 55 | 回答提示: 56 | 57 | ①最重要的是:应聘者要使找招聘单位相信,应聘者在过往的单位的“离职原因”在此家招聘单位里不存在; 58 | 59 | ②避免把“离职原因”说得太详细、太具体; 60 | 61 | ③不能掺杂主观的负面感受,如“太辛苦”、“人际关系复杂”、“管理太混乱”、“公司不重视人才”、“公司排斥我们某某的员工”等; 62 | 63 | ④但也不能躲闪、回避,如“想换换环境”、“个人原因”等; 64 | 65 | ⑤不能涉及自己负面的人格特征,如不诚实、懒惰、缺乏责任感、不随和等; 66 | 67 | ⑥尽量使解释的理由为应聘者个人形象添彩; 68 | 69 | ⑦相关例子:如“我离职是因为这家公司倒闭;我在公司工作了三年多,有较深的感情;从去年始,由于市场形势突变,公司的局面急转直下;到眼下这一步我觉得很遗憾,但还要面对显示,重新寻找能发挥我能力的舞台。”同一个面试问题并非只有一个答案,而同一个答案并不是在任何面试场合都有效,关键在应聘者掌握了规律后,对面试的具体情况进行把握,有意识地揣摩面试官提出问题的心理背景,然后投其所好。 70 | 71 | 分析:除非是薪资太低,或者是最初的工作,否则不要用薪资作为理由。“求发展”也被考官听得太多,离职理由要根据每个人的真实离职理由来设计,但是在回答时一定要表现得真诚。实在想不出来的时候,家在外地可以说是因为家中有事,须请假几个月,公司又不可能准假,所以辞职。这个答案一般面试官还能接受。 72 | 73 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 74 | 75 | 微信公众号名称:Android干货程序员 76 | 77 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /Java/115个Java面试题及回答.md: -------------------------------------------------------------------------------- 1 | ## 115个Java面试题及回答 2 | 3 | 简介 在本教程中,我们将讨论在Java面试中,用人单位用来测试应聘者Java以及面向对象的能力的面试题目.以下章节我们将按照以下结构讨论面试问题,面向对象编程及其特性,Java及其特性的一般问题,集合,垃圾回收,异常处理,Java applets,Swing,JDBC,RMI, Servlet 和 JSP. 来,我们一起出发吧。 4 | 5 | [115个Java面试题及回答](https://github.com/snowdream/115-Java-Interview-Questions-and-Answers/tree/master/zh) -------------------------------------------------------------------------------- /Java/Java面试题-1.md: -------------------------------------------------------------------------------- 1 | ### 1. JRE与JDK的区别? 2 | 3 | JRE:java运行时的环境,JDK:包含JRE并且可以查看源码 4 | 5 | ### 2. Java中的数据类型都有哪些? 6 | 7 | 分别是8种基本数据类型:byte、short、int、long、float、double、boolean、char 8 | 9 | 除8种以外统称为引用类型,例如:String类、Object类、数组及自己创建的类等 10 | 11 | ### 3. 等号“==”与equals的区别? 12 | 13 | "=="比较的是栈上的值(基本数据类型比较值的方式) 14 | 15 | equlas比较的是堆上的值(引用类型比较值的方式) 16 | 17 | ### 4. i++与++i的区别? 18 | 19 | i++为代码执行后自加1,++i为代码执行前自加1 20 | 21 | ### 5. break和continue和return的区别? 22 | 23 | break:跳出整个循环,continue:跳出本次循环,进入下一次循环,return:跳出方法,结束这个方法,并返回一个数据 24 | 25 | ### 6. int类型和String类型之间的互相转换? 26 | 27 | int -->String常用的方法: 28 | 29 | - 字符串拼接 30 | 31 | - String b = String.valueof(int a)方法 32 | 33 | String -->int常用的方法: 34 | 35 | - int i = Integer.valueof(String a)方法 36 | 37 | - int i = Integer.parseInt(String a)方法 38 | 39 | ### 7. &、|与&&、||的区别? 40 | 41 | &、| :为位运算符可以进行位运算,符号两边都需要判断才会结束判断,效率低 42 | 43 | &&、||:为逻辑判断符用来进行逻辑判断,从左到右判断,一面为否就结束判断,效率高 44 | 45 | ### 8. swich()语句中小括号能使用String类型数据么? 46 | 47 | - 只用JDK1.7版本以后才可以使用String类型数据 48 | - long类型数据任何版本都不可以使用 49 | 50 | ### 9. 循环都有哪些? 51 | 52 | - for循环 53 | - for each循环 54 | - while循环 55 | - do while 循环 (先执行一次) 56 | - 递归(方法自己调用自己) 57 | 58 | ### 10. 类的结构是什么? 59 | 60 | - 成员变量 61 | - 构造器(构造方法)(不可以被static修饰) 62 | - 普通方法 63 | - 代码块 64 | - 内部类 65 | 66 | ### 11. 图解java面试题 - JVM 67 | 68 | 内容大纲 69 | 70 | ![img](img/jvm1.png) 71 | 72 | GC是什么?为什么要有GC? 73 | 74 | ![img](img/jvm2.png) 75 | 76 | 垃圾回收的优点和原理,并考虑两种回收机制 77 | 78 | ![img](img/jvm3.png) 79 | 80 | 垃圾回收器的基本原理是什么 81 | 82 | ![img](img/gc基本原理.png) 83 | 84 | Java中会有内存泄漏吗 85 | 86 | ![img](img/jvm4.png) 87 | 88 | ClassLoader如何加载class 89 | 90 | ![img](img/jvm5.png) 91 | 92 | JVM内存模型图 93 | 94 | ![img](img/jvm6.png) -------------------------------------------------------------------------------- /Java/Java高级软件工程师面试考纲.md: -------------------------------------------------------------------------------- 1 | 如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构、算法、网络、操作系统等知识。因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对Java高级开发工程师职位的考核纲要,希望可以帮助到需要的人。 2 | 3 | 当前,市面上有《Java XX宝典》类似的图书,而且图书中的内容都着重在讲解Java最为基础的部分,最严重的是,里面有着大量错误的内容,极具误导性。另外,网上也有各种各样的[Java面试题](http://www.codeceo.com/article/tag/java%E9%9D%A2%E8%AF%95%E9%A2%98),很多也是着重在Java语言基础上。实际上,如果要应聘高级开发工程师职务,仅仅懂得Java的基础知识是远远不够的,还必须懂得常用数据结构、算法、网络、操作系统等知识。因此本文不会讲解具体的技术,笔者综合自己应聘各大公司的经历,整理了一份大公司对Java高级开发工程师职位的考核纲要,希望可以帮助到需要的人。 4 | 5 | ## 1 Java基础 6 | 7 | **1.1 Collection和Map** 8 | 9 | (1)掌握Collection和Map的继承体系。 10 | 11 | (2)掌握ArrayList、LinkedList、Vector、Stack、PriorityQueue、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap、TreeMap、[WeakHashMap](http://www.codeceo.com/article/java-weakhashmap-source.html)、EnumMap、TreeMap、HashTable的特点和实现原理。 12 | 13 | (3)掌握CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentHashMap的实现原理和适用场景。 14 | 15 | **1.2 IO** 16 | 17 | (1)掌握InputStream、OutputStream、Reader、Writer的继承体系。 18 | 19 | (2)掌握字节流(FileInputStream、DataInputStream、BufferedInputStream、FileOutputSteam、DataOutputStream、BufferedOutputStream)和字符流(BufferedReader、InputStreamReader、FileReader、BufferedWriter、OutputStreamWriter、PrintWriter、FileWriter),并熟练运用。 20 | 21 | (3)掌握NIO实现原理及使用方法。 22 | 23 | **1.3 异常** 24 | 25 | (1)掌握Throwable继承体系。 26 | 27 | (2)掌握异常工作原理。 28 | 29 | (3)了解常见受检异常(比如FileNotFoundException)、非受检异常(比如NullPointerException)和错误(比如IOError)。 30 | 31 | **1.4 多线程** 32 | 33 | (1)掌握[Executor](http://www.codeceo.com/article/java-executor-learning.html)s可以创建的三种(JAVA8增加了一种,共四种)线程池的特点及适用范围。 34 | 35 | (2)掌握多线程同步机制,并熟练运用。 36 | 37 | **1.5 Socket** 38 | 39 | (1)掌握Socket通信原理。 40 | 41 | (2)熟练使用多线程结合Socket进行编程。 42 | 43 | ## 2 Java虚拟机 44 | 45 | **2.1 JVM内存区域划分** 46 | 47 | (1)掌握程序计数器、堆、虚拟机栈、本地方法栈、方法区(JAVA8已移除)、元空间(JAVA8新增)的作用及基本原理。 48 | 49 | (2)掌握堆的划分:新生代(Eden、Survivor1、Survivor2)和老年代的作用及工作原理。 50 | 51 | (3)掌握JVM内存参数设置及调优。 52 | 53 | **2.2 类加载** 54 | 55 | (1)掌握类的加载阶段:加载、链接(验证、准备、解析)、初始化、使用、卸载。 56 | 57 | (2)掌握类加载器分类及其应用:启动类加载器、扩展类加载器、应用程序类加载器、自定义加载器。 58 | 59 | ## 3 J2EE 60 | 61 | (1) 掌握JSP内置对象、动作及相关特点和工作原理。 62 | 63 | (2) 掌握Servlet的特点和工作原理。 64 | 65 | (3) 掌握Spring框架的IOC和AOP实现原理(反射和动态代理)。 66 | 67 | (4) 至少掌握一个[MVC框架](http://www.codeceo.com/article/mvc-framework-mvc-design.html)(Spring MVC,Struts等)的工作原理,并熟练运用。 68 | 69 | (5) 至少掌握一个ORM框架(Hibernate,MyBatis等)的工作原理,并熟练运用。 70 | 71 | ## 4 数据结构与算法 72 | 73 | (1)掌握线性表和树的特点并熟练运用。 74 | 75 | (2)掌握常用排序和查找算法:插入排序(直接插入排序、希尔排序)、选择排序(直接选择排序、堆排序)、交换排序(冒泡排序、快速排序)、归并排序,顺序查找、[二分查找](http://www.codeceo.com/article/binary-search.html)、哈希查找。 76 | 77 | (3) 熟练运用常见排序和查找算法思想解决编程问题。 78 | 79 | (4)了解几大基本算法:[贪心算法](http://www.codeceo.com/article/greedy-algorithm.html)、分治策略、动态规划。 80 | 81 | ## 5 计算机网络 82 | 83 | (1)掌握网络的分层结构,及每层的功能特点。 84 | 85 | (2)掌握TCP/IP的通信原理(三次握手、四次挥手) 86 | 87 | ## 6 数据库 88 | 89 | (1)掌握复杂的SQL语句编写。 90 | 91 | (2)掌握数据库的优化(SQL层面和表设计层面)。 92 | 93 | (3)至少掌握一款数据库产品。 94 | 95 | (4)熟悉高并发、大数据情况下的数据库开发。 96 | 97 | ## 7 Web技术 98 | 99 | (1)掌握AJAX的工作原理。 100 | 101 | (2)至少熟悉一款JS框架(比如JQuery)。 102 | 103 | ## 8 [设计模式](http://www.codeceo.com/article/category/develop/design-patterns) 104 | 105 | (1)熟悉常见的设计模式。 106 | 107 | (2)会将设计模式理论应用到实际开发中。 108 | 109 | ## 9 Linux 110 | 111 | (1)熟练运用Linux常见命令。 112 | 113 | (2)熟悉Linux操作系统基本概念及特点。 114 | 115 | (3)熟悉Shell脚本。 116 | 117 | ## 10 操作系统 118 | 119 | (1)掌握操作系统的进程管理。 120 | 121 | (2)了解操作系统的I/O。 122 | 123 | ## 11 正则表达式 124 | 125 | (1)掌握常见正则表达式符号。 126 | 127 | (2)熟练运用正则表达式解决实际问题(比如匹配电话号码、邮箱、域名等)。 -------------------------------------------------------------------------------- /Java/README.md: -------------------------------------------------------------------------------- 1 | ## Java面试题 2 | 3 | - [深拷贝浅拷贝](深拷贝浅拷贝.md) 4 | - [数据库求差](数据库求差.md) 5 | - [Java面试题-1](Java面试题-1.md) 6 | - [Java面试题-2](Java面试题-2.md) 7 | - [Java高级软件工程师面试考纲](Java高级软件工程师面试考纲.md) 8 | - [66道经典的Java基础面试题集锦](66道经典的Java基础面试题集锦.md) 9 | - [115个Java面试题及回答](115个Java面试题及回答.md) 10 | - [J2SE基础面试核心内容](J2SE基础面试核心内容.md) 11 | - [J2SE高级面试核心内容](J2SE高级面试核心内容.md) -------------------------------------------------------------------------------- /Java/img/clone1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/clone1.png -------------------------------------------------------------------------------- /Java/img/clone2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/clone2.png -------------------------------------------------------------------------------- /Java/img/clone3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/clone3.png -------------------------------------------------------------------------------- /Java/img/gc基本原理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/gc基本原理.png -------------------------------------------------------------------------------- /Java/img/java内存模型.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/java内存模型.jpg -------------------------------------------------------------------------------- /Java/img/jdbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jdbc.png -------------------------------------------------------------------------------- /Java/img/jvm1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm1.png -------------------------------------------------------------------------------- /Java/img/jvm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm2.png -------------------------------------------------------------------------------- /Java/img/jvm3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm3.png -------------------------------------------------------------------------------- /Java/img/jvm4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm4.png -------------------------------------------------------------------------------- /Java/img/jvm5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm5.png -------------------------------------------------------------------------------- /Java/img/jvm6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/jvm6.png -------------------------------------------------------------------------------- /Java/img/斐波那契数列.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/斐波那契数列.png -------------------------------------------------------------------------------- /Java/img/随机排序.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/Java/img/随机排序.png -------------------------------------------------------------------------------- /Java/数据库求差.md: -------------------------------------------------------------------------------- 1 | 今日,有同学跟我说他在最近在面试的时候,面试官问了他一个很简单的问题,结果他一脸懵逼,他可是有过一年开发经验的,怎么可能会在面试的时候马失前蹄了呢?大家来看下他的问题你们会不会。 2 | 3 | ![img](http://www.10tiao.com/img.do?url=http%3A//mmbiz.qpic.cn/mmbiz_jpg/3aGGuJWRuJc7PgjGWJCIOVuGNNK96RCSicx4e1PXo9PDQFr53A30iakbx5yZHsicNynHetU2LA8ib5EiaRmyYhaRIPg/0%3Fwx_fmt%3Djpeg) 4 | 5 | 是很简单的问题吧 6 | 7 | 我一看,这问题糟了,我也不知道,是很尴尬,我就给了我们公司一位大牛,结果大牛神秘兮兮的给了一张图 8 | 9 | ![img](http://www.10tiao.com/img.do?url=http%3A//mmbiz.qpic.cn/mmbiz_jpg/3aGGuJWRuJc7PgjGWJCIOVuGNNK96RCScFmic7MYlFtryBFSoYORsEXNyRguDLWqkNVsRibrqAUqicKuTT93TsFdg/0%3Fwx_fmt%3Djpeg) 10 | 11 | 这一下子我就看懂了,但我就是不说,我就也给他回了这张图 12 | 13 | ![img](http://www.10tiao.com/img.do?url=http%3A//mmbiz.qpic.cn/mmbiz_jpg/3aGGuJWRuJc7PgjGWJCIOVuGNNK96RCS5PokXV5qDtM5SXCoLc4j9LqZ6T3ZkW8dXHQ6mpD7mabNPicAUBKEVcA/0%3Fwx_fmt%3Djpeg) 14 | 15 | 这是后来他回我的 16 | 17 | 但是,不得不说,他还是可以的,一下子他也看懂了,原来这就是个小问题,但是就是这个小细节,他却错失了一次很好的机会。 18 | 19 | ![img](http://www.10tiao.com/img.do?url=http%3A//mmbiz.qpic.cn/mmbiz_jpg/3aGGuJWRuJc7PgjGWJCIOVuGNNK96RCSTAQic0MyRc5haDx1O7kf3wG6WxrHBsNsickktFzHRPWlkAPcIVPLtticw/0%3Fwx_fmt%3Djpeg) 20 | 21 | 我也帮大家整理了一些网上面网友遇到过的古怪面试题。可能不全,但也会帮到大家的吧 22 | 23 | 1、 使用两种方式写出SingleTon. 24 | 25 | 2、 简单绘制出Sun Hotspot VM的内存结构。并简单说明各自的作用。 26 | 27 | 3、 实现一个用于生产者-消费者模式的队列。假设队列的固定长度为10,FULL的时候只能消费不能生产,EMPTY的时候只能生产不能消费。 28 | 29 | 4、 调用A线程的interrupt方法,其在什么情况下会抛出InterruptException(不考虑网络IO的情况) 30 | 31 | 5、 Sevlet容器如何使用cookie跟踪回话?response.encodeURL(URL)什么情况下生效? 32 | 33 | 6、 DOM与SAX方式解析XML文件的原理?各自适用的场景是什么? 34 | 35 | 7、 将一个byte值转化为int值为什么要与0Xff进行&运算? 36 | 37 | 答案呢,在下面 38 | 39 | 1.至少有3种写法 40 | 41 | 2.新生代(eden+2survisor) 老年代 持久代 42 | 43 | 3.可考虑blockingqueue 44 | 45 | 4.该线程在wait或者sleep时 46 | 47 | 5.cookie里边有session id的内容。 48 | 49 | 6.dom是一口吃,生成节点树~另一个基于事件处理 50 | 51 | 7.8->32位 52 | 53 | 试题都很简单,但是越微小越容易出错,编程更是这样,虽然现在代码都会报错,但是我们也应该养成注意细节的好习惯。 -------------------------------------------------------------------------------- /Java/深拷贝浅拷贝.md: -------------------------------------------------------------------------------- 1 | “纵使面试无数,难敌考官吃素“,昨天去乐视面试,遇到一个从来没有遇到过的考题! 2 | 3 | ## 请分别实现深度和浅读的对象克隆? 4 | 5 | 原理:深度克隆和浅度克隆,Object中的克隆方法是浅度克隆。JDK规定了克隆需要满足的一些条件,简要总结一下就是:对某个对象进行克隆,对象的的成员变量如果包括引用类型或者数组,那么克隆的时候其实是不会把这些对象也带着复制到克隆出来的对象里面的,只是复制一个引用,这个引用指向被克隆对象的成员对象,但是基本数据类型是会跟着被带到克隆对象里面去的。而深度可能就是把对象的所有属性都统统复制一份新的到目标对象里面去。简单画个对比图: 6 | 7 | ![img](img/clone1.png) 8 | 9 | ![img](img/clone2.png) 10 | 11 | ## 实现方式 12 | 13 | - 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆; 14 | 15 | - 实现Cloneable接口并重写Object类中的clone()方法,即可实现浅度克隆。 16 | 17 | 代码 18 | 19 | Car.java 20 | ```java 21 | public class Car implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private String brand;//品牌 26 | private int maxSpeed;//最高时速 27 | 28 | public Car(String brand, int maxSpeed) { 29 | this.brand = brand; 30 | this.maxSpeed = maxSpeed; 31 | } 32 | 33 | public String getBrand() { 34 | return brand; 35 | } 36 | 37 | public void setBrand(String brand) { 38 | this.brand = brand; 39 | } 40 | 41 | public int getMaxSpeed() { 42 | return maxSpeed; 43 | } 44 | 45 | public void setMaxSpeed(int maxSpeed) { 46 | this.maxSpeed = maxSpeed; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "Car{" + 52 | "brand='" + brand + '\'' + 53 | ", maxSpeed=" + maxSpeed + 54 | '}'; 55 | } 56 | } 57 | ``` 58 | Person.java 59 | ```java 60 | public class Person implements Serializable { 61 | private static final long serialVersionUID = 1L; 62 | 63 | private String name;//姓名 64 | private int age;//年龄 65 | private Car car;//座驾 66 | 67 | public Person(String name, int age, Car car) { 68 | this.name = name; 69 | this.age = age; 70 | this.car = car; 71 | } 72 | 73 | public String getName() { 74 | return name; 75 | } 76 | 77 | public void setName(String name) { 78 | this.name = name; 79 | } 80 | 81 | public int getAge() { 82 | return age; 83 | } 84 | 85 | public void setAge(int age) { 86 | this.age = age; 87 | } 88 | 89 | public Car getCar() { 90 | return car; 91 | } 92 | 93 | public void setCar(Car car) { 94 | this.car = car; 95 | } 96 | 97 | @Override 98 | public String toString() { 99 | return "Person{" + 100 | "name='" + name + '\'' + 101 | ", age=" + age + 102 | ", car=" + car + 103 | '}'; 104 | } 105 | } 106 | ``` 107 | Person2.java 108 | ```java 109 | public class Person2 implements Serializable { 110 | private static final long serialVersionUID = 1L; 111 | 112 | private String name;//姓名 113 | private int age;//年龄 114 | private Car car;//座驾 115 | 116 | public Person2(String name, int age, Car car) { 117 | this.name = name; 118 | this.age = age; 119 | this.car = car; 120 | } 121 | 122 | public String getName() { 123 | return name; 124 | } 125 | 126 | public void setName(String name) { 127 | this.name = name; 128 | } 129 | 130 | public int getAge() { 131 | return age; 132 | } 133 | 134 | public void setAge(int age) { 135 | this.age = age; 136 | } 137 | 138 | public Car getCar() { 139 | return car; 140 | } 141 | 142 | public void setCar(Car car) { 143 | this.car = car; 144 | } 145 | 146 | @Override 147 | protected Object clone(){ 148 | Person2 s= null; 149 | try { 150 | s = (Person2) Person2.super.clone(); 151 | } catch (CloneNotSupportedException e) { 152 | e.printStackTrace(); 153 | } 154 | return s; 155 | } 156 | 157 | @Override 158 | public String toString() { 159 | return "Person{" + 160 | "name='" + name + '\'' + 161 | ", age=" + age + 162 | ", car=" + car + 163 | '}'; 164 | } 165 | } 166 | ``` 167 | CloneUtil.java 168 | ```java 169 | public class CloneUtil { 170 | 171 | private CloneUtil() { 172 | throw new AssertionError(); 173 | } 174 | 175 | public static T clone(T object) throws IOException, 176 | ClassNotFoundException { 177 | // 说明:调用ByteArrayOutputStream或ByteArrayInputStream对象的close方法没有任何意义 178 | // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外资源(如文件流)的释放 179 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 180 | ObjectOutputStream oos = new ObjectOutputStream(baos); 181 | oos.writeObject(object); 182 | 183 | ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 184 | ObjectInputStream ois = new ObjectInputStream(bais); 185 | return (T) ois.readObject(); 186 | } 187 | } 188 | ``` 189 | CloneTest 190 | ```java 191 | public class CloneTest { 192 | public static void main(String[] args){ 193 | try { 194 | // 深拷贝 195 | Person p1 = new Person("xiaoming",18,new Car("Benz",300)); 196 | Person p2 = CloneUtil.clone(p1); 197 | // 修改克隆的Person对象p2关联的汽车对象的品牌属性 198 | // 原来的Person对象p1关联的汽车不会受到任何影响,还是Benz 199 | // 因为在克隆Person对象时其关联的汽车对象也被克隆了 200 | 201 | p2.setAge(25); 202 | p2.getCar().setBrand("BYD"); 203 | 204 | System.out.println(p1); 205 | 206 | Person2 p3 = new Person2("xiaoming",18,new Car("Benz",300)); 207 | Person2 p4 = (Person2) p3.clone(); 208 | p4.setAge(25); 209 | p4.getCar().setBrand("BYD"); 210 | 211 | System.out.println(p3); 212 | } catch (Exception e) { 213 | e.printStackTrace(); 214 | } 215 | } 216 | } 217 | ``` 218 | 结果 219 | ![img](img/clone3.png) -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [前言](README.md) 4 | * [Android视频教程](Android/Android视频教程.md) 5 | * [BAT大咖助力,全面升级Android面试](Android/BAT大咖助力全面升级Android面试.md) 6 | * [Android高级面试,10大开源框架源码解析](Android/Android高级面试10大开源框架源码解析.md) 7 | * [Android](Android/README.md) 8 | * [Android基础面试核心内容](Android/Android基础面试核心内容.md) 9 | * [Android面试精华题目总结](Android/Android面试精华题目总结.md) 10 | * [Android面试题-1](Android/Android面试题-1.md) 11 | * [Android面试题-2](Android/Android面试题-2.md) 12 | * [Android面试重点](Android/Android面试重点.md) 13 | * [接口安全](Android/接口安全.md) 14 | * [平台架构](Android/平台架构.md) 15 | * [源码分析相关面试题](源码分析/README.md) 16 | * [Volley源码剖析](源码分析/Volley源码剖析.md) 17 | * [注解框架内部实现原理](源码分析/注解框架内部实现原理.md) 18 | * [okhttp内核剖析](源码分析/okhttp内核剖析.md) 19 | * [Android源码编译实现静默安装和静默偷拍](源码分析/Android源码编译实现静默安装和静默偷拍.md) 20 | * [Activity相关面试题](Activity/README.md) 21 | * [onSaveInstanceState源码内核分析](Activity/onSaveInstanceState源码内核分析.md) 22 | * [深刻剖析activity启动模式-1](Activity/深刻剖析activity启动模式-1.md) 23 | * [深刻剖析activity启动模式-2](Activity/深刻剖析activity启动模式-2.md) 24 | * [深刻剖析activity启动模式-3](Activity/深刻剖析activity启动模式-3.md) 25 | * [Activity Task和Process之间的关系](Activity/Activity Task和Process.md) 26 | * [为什么service里面startActivity抛异常](Activity/为什么service里面startActivity抛异常.md) 27 | * [App优雅退出](Activity/App优雅退出.md) 28 | * [onCreate源码分析](Activity/onCreate源码分析.md) 29 | * [Service相关面试题](Service/README.md) 30 | * [IntentService源码分析](Service/IntentService源码分析.md) 31 | * [Service是否在main thread中执行, service里面是否能执行耗时的操作?](Service/Android面试题-Service.md) 32 | * [Android面试题-Service不死之身](Service/Android面试题-Service不死之身.md) 33 | * [与XMPP相关面试题](网络编程/README.md) 34 | * [阐述一下对XMPP协议理解以及优缺点?](网络编程/阐述一下对XMPP协议理解以及优缺点?.md) 35 | * [简单阐述一下及时推送原理?](网络编程/简单阐述一下及时推送原理?.md) 36 | * [与性能优化相关面试题](性能优化/README.md) 37 | * [内存泄漏和内存溢出区别](性能优化/与性能优化相关试题一.md) 38 | * [UI优化和线程池实现原理](性能优化/与性能优化相关试题二.md) 39 | * [代码优化](性能优化/与性能优化相关试题三.md) 40 | * [Android应用UI性能分析](性能优化/Android应用UI性能分析.md) 41 | * [内存泄漏监测](性能优化/内存泄漏监测.md) 42 | * [App应用启动分析与优化](性能优化/App应用启动分析与优化.md) 43 | * [与IPC机制相关面试题](性能优化/与IPC机制相关面试题.md) 44 | * [与登录相关面试题](登陆注册/README.md) 45 | * [Oauth的实现原理](登陆注册/Oauth的实现原理.md) 46 | * [Token的实际意义](登陆注册/Token的实际意义.md) 47 | * [微信扫码登录内部实现原理](登陆注册/微信扫码登录内部实现原理.md) 48 | * [与开发相关面试题](开发遇到的问题/README.md) 49 | * [迭代开发的时候如何向前兼容新旧接口?](开发遇到的问题/迭代开发的时候如何向前兼容新旧接口?.md) 50 | * [手把手教你如何解决as jar包冲突](开发遇到的问题/手把手教你如何解决as jar包冲突.md) 51 | * [Context原理分析](开发遇到的问题/Context原理分析.md) 52 | * [解决ViewPager.setCurrentItem中间很多页面切换方案](开发遇到的问题/终极解决ViewPager.setCurrentItem中间页面过多解决方案.md) 53 | * [解决字体适配](开发遇到的问题/解决字体适配.md) 54 | * [软键盘顶出去解决方案](开发遇到的问题/软键盘顶出去解决方案.md) 55 | * [机型适配之痛](开发遇到的问题/机型适配之痛.md) 56 | * [ViewPager和Fragment使用过程中会遇到哪些问题](开发遇到的问题/ViewPager和Fragment使用过程中会遇到哪些问题.md) 57 | * [与人事相关面试题](HR/README.md) 58 | * [人事面试宝典一之自我介绍](HR/人事面试宝典一之自我介绍.md) 59 | * [人事面试宝典二之离职](HR/人事面试宝典二之离职.md) 60 | * [人事面试宝典](HR/人事面试宝典.md) 61 | * [网络编程](网络编程/README.md) 62 | * [Android客户端和服务端如何使用Token和Session](网络编程/Android客户端和服务端如何使用Token和Session.md) 63 | * [推送原理](网络编程/推送原理.md) 64 | * [Java面试题](Java/README.md) 65 | * [深拷贝浅拷贝](Java/深拷贝浅拷贝.md) 66 | * [数据库求差](Java/数据库求差.md) 67 | * [Java面试题-1](Java/Java面试题-1.md) 68 | * [Java面试题-2](Java/Java面试题-2.md) 69 | * [Java高级软件工程师面试考纲](Java/Java高级软件工程师面试考纲.md) 70 | * [66道经典的Java基础面试题集锦](Java/66道经典的Java基础面试题集锦.md) 71 | * [115个Java面试题及回答](Java/115个Java面试题及回答.md) 72 | * [J2SE基础面试核心内容](Java/J2SE基础面试核心内容.md) 73 | * [J2SE高级面试核心内容](Java/J2SE高级面试核心内容.md) 74 | * [面试技巧](面试技巧/README.md) 75 | * [程序员面试宝典](面试技巧/程序员面试宝典.md) 76 | * [罗永浩新东方万字求职信](面试技巧/罗永浩新东方万字求职信.md) 77 | * [我在面试中最喜欢问开发者的问题,和回答思路](面试技巧/我在面试中最喜欢问开发者的问题,和回答思路.md) 78 | * [经验分享](经验分享/README.md) 79 | * [我为什么要离开华为?](经验分享/我为什么要离开华为?.md) 80 | * [工作三年后,我选择离开腾讯](经验分享/工作三年后,我选择离开腾讯.md) 81 | * [一个程序员的血泪史](经验分享/一个程序员的血泪史.md) 82 | * [我为什么离开锤子科技?](经验分享/我为什么离开锤子科技?.md) 83 | * [互联网巨头BAT3内部员工的真实状况](经验分享/互联网巨头BAT3内部员工的真实状况.md) 84 | * [扫清Android面试障碍](经验分享/扫清Android面试障碍.md) 85 | * [史上最全 Android 面试资料集合](经验分享/史上最全 Android 面试资料集合.md) 86 | * [2016年4月某公司面试题及面试流程](经验分享/2016年4月某公司面试题及面试流程.md) 87 | * [2017届实习生招聘面经](经验分享/2017届实习生招聘面经.md) 88 | * [国内一线互联网公司内部面试题库](经验分享/国内一线互联网公司内部面试题库.md) 89 | * [互联网公司面试经验总结](经验分享/互联网公司面试经验总结.md) 90 | * [一个五年Android开发者百度、阿里、聚美、映客的面试心经](经验分享/一个五年Android开发者百度、阿里、聚美、映客的面试心经.md) 91 | * [腾讯公司程序员面试题及答案详解](经验分享/腾讯公司程序员面试题及答案详解.md) 92 | * [面试心得与总结:BAT、网易、蘑菇街 ](经验分享/面试心得与总结:BAT、网易、蘑菇街 .md) 93 | * [阿里+百度+CVTE面经合集](经验分享/阿里+百度+CVTE面经合集.md) 94 | * [技术硬碰硬—阳哥带你玩转上海Android招聘市场](经验分享/技术硬碰硬—阳哥带你玩转上海Android招聘市场.md) 95 | * [Android 曲折的求职之路](经验分享/Android 曲折的求职之路.md) 96 | * [杭州找 Android 工作的点点滴滴](经验分享/杭州找 Android 工作的点点滴滴.md) 97 | * [给培训班出来的一点不成熟的小建议](经验分享/给培训班出来的一点不成熟的小建议.md) 98 | * [Android 暑期实习生面试经验谈](经验分享/Android 暑期实习生面试经验谈.md) 99 | -------------------------------------------------------------------------------- /Service/Android面试题-Service.md: -------------------------------------------------------------------------------- 1 | **Android面试题-Service是否在main thread中执行, service里面是否能执行耗时的操作?** 2 | 3 | Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作(比如:网络请求,拷贝数据库,大文件),否则会引起ANR。 4 | 5 | 如果想在服务中执行耗时的任务。有以下解决方案: 6 | 7 | 1) 在service中开启一个子线程 8 | 9 | ``` 10 | new Thread(){}.start(); 11 | ``` 12 | 13 | 2) 可以使用IntentService异步管理服务 14 | 参考文章IntentService的使用: 15 | [http://blog.csdn.net/mwq384807683/article/details/72549222](http://blog.csdn.net/mwq384807683/article/details/72549222) 16 | 17 | Service 和 Activity 在同一个线程,对于同一 app 来说默认情况下是在同一个线程中的 main Thread (UI Thread) -------------------------------------------------------------------------------- /Service/Android面试题-Service不死之身.md: -------------------------------------------------------------------------------- 1 | ### 1. 在onStartCommand方法中将flag设置为START_STICKY; 2 | 3 | ``` 4 | return Service.START_STICKY; 5 | ``` 6 | 7 | ### 2. 在xml中设置了android:priority 8 | 9 | ```xml 10 | 11 | 14 | 15 | ``` 16 | 17 | ### 3. 在onStartCommand方法中设置为前台进程 18 | 19 | ```java 20 | @Override 21 | public int onStartCommand(Intent intent, int flags, int startId) { 22 | Notification notification = new Notification(R.mipmap.ic_launcher, "服务正在运行",System.currentTimeMillis()); 23 | Intent notificationIntent = new Intent(this, MainActivity.class); 24 | PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,notificationIntent,0); 25 | RemoteViews remoteView = new RemoteViews(this.getPackageName(),R.layout.notification); 26 | remoteView.setImageViewResource(R.id.image, R.mipmap.ic_launcher); 27 | remoteView.setTextViewText(R.id.text , "Hello,this message is in a custom expanded view"); 28 | notification.contentView = remoteView; 29 | notification.contentIntent = pendingIntent; 30 | startForeground(1, notification); 31 | return Service.START_STICKY; 32 | 33 | } 34 | ``` 35 | 36 | ### 4. 在onDestroy方法中重启service 37 | 38 | ```java 39 | @Override 40 | public void onDestroy() { 41 | super.onDestroy(); 42 | startService(new Intent(this, MyService.class)); 43 | } 44 | ``` 45 | 46 | ### 5. 用AlarmManager.setRepeating(...)方法循环发送闹钟广播,接收的时候调用service的onstart方法 47 | 48 | ```java 49 | Intent intent = new Intent(MainActivity.this,MyAlarmReciver.class); 50 | PendingIntent sender = PendingIntent.getBroadcast( MainActivity.this, 0, intent, 0); 51 | 52 | // We want the alarm to go off 10 seconds from now. 53 | Calendar calendar = Calendar.getInstance(); 54 | calendar.setTimeInMillis(System.currentTimeMillis()); 55 | calendar.add(Calendar.SECOND, 1); 56 | AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 57 | //重复闹钟 58 | /** 59 | * @param type 60 | * @param triggerAtMillis t 闹钟的第一次执行时间,以毫秒为单位 61 | * go off, using the appropriate clock (depending on the alarm type). 62 | * @param intervalMillis 表示两次闹钟执行的间隔时间,也是以毫秒为单位 63 | * of the alarm. 64 | * @param operation 绑定了闹钟的执行动作,比如发送一个广播、给出提示等等 65 | */ 66 | am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 2 * 1000, sender); 67 | ``` 68 | 69 | ### 6. 目前市场面的很多三方的消息推送SDK唤醒APP,例如Jpush 70 | 71 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ac7fa1011763eae3?imageMogr2/auto-orient/strip) 72 | 73 | ### **总结** 74 | 75 | 这纯粹是面试的时候忽悠一下面试官,不代表着你的Service就永生不死了,只能说是提高了进程的优先级。迄今为止我没有发现能够通过常规方法达到流氓需求(通过长按home键清除都清除不掉)的方法,目前所有方法都是指通过Android的内存回收机制和普通的第三方内存清除等手段后仍然保持运行的方法,有些手机厂商把这些知名的app放入了自己的白名单中,保证了进程不死来提高用户体验(如微信、QQ、陌陌都在小米的白名单中)。如果从白名单中移除,他们终究还是和普通app一样躲避不了被杀的命运。 -------------------------------------------------------------------------------- /Service/IntentService源码分析.md: -------------------------------------------------------------------------------- 1 | IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。 2 | 3 | 而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 4 | 5 | ### **IntentService有什么好处呢?** 6 | 7 | 1)我们省去了在Service中手动开线程的麻烦, 8 | 9 | 2)当操作完成时,我们不用手动停止Service。 10 | 11 | 接下来让我们来看看如何使用,写一个Demo来模拟两个耗时操作,Operation1与Operation2,先执行1,2必须等1执行完才能执行2: 12 | 13 | 新建工程,新建一个继承IntentService的类,我这里是IntentServiceDemo.java 14 | 15 | ```java 16 | public class IntentServiceDemo extends IntentService { 17 | 18 | public IntentServiceDemo() { 19 | //必须实现父类的构造方法 20 | super("IntentServiceDemo"); 21 | } 22 | 23 | @Override 24 | public IBinder onBind(Intent intent) { 25 | System.out.println("onBind"); 26 | return super.onBind(intent); 27 | } 28 | 29 | 30 | @Override 31 | public void onCreate() { 32 | System.out.println("onCreate"); 33 | super.onCreate(); 34 | } 35 | 36 | @Override 37 | public void onStart(Intent intent, int startId) { 38 | System.out.println("onStart"); 39 | super.onStart(intent, startId); 40 | } 41 | 42 | 43 | @Override 44 | public int onStartCommand(Intent intent, int flags, int startId) { 45 | System.out.println("onStartCommand"); 46 | return super.onStartCommand(intent, flags, startId); 47 | } 48 | 49 | 50 | @Override 51 | public void setIntentRedelivery(boolean enabled) { 52 | super.setIntentRedelivery(enabled); 53 | System.out.println("setIntentRedelivery"); 54 | } 55 | 56 | @Override 57 | protected void onHandleIntent(Intent intent) { 58 | //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务 59 | System.out.println("currentThread()=" + Thread.currentThread().getName()); 60 | String action = intent.getExtras().getString("param"); 61 | if (action.equals("oper1")) { 62 | System.out.println("Operation1"); 63 | }else if (action.equals("oper2")) { 64 | System.out.println("Operation2"); 65 | } 66 | 67 | try { 68 | Thread.sleep(2000); 69 | } catch (InterruptedException e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | 74 | @Override 75 | public void onDestroy() { 76 | System.out.println("onDestroy"); 77 | super.onDestroy(); 78 | } 79 | 80 | } 81 | ``` 82 | 83 | 我把生命周期方法全打印出来了,待会我们来看看它执行的过程是怎样的。接下来是Activity,在Activity中来启动IntentService: 84 | 85 | ```java 86 | public class TestActivity extends Activity { 87 | /** Called when the activity is first created. */ 88 | @Override 89 | public void onCreate(Bundle savedInstanceState) { 90 | super.onCreate(savedInstanceState); 91 | setContentView(R.layout.main); 92 | 93 | //可以启动多次,每启动一次,就会新建一个work thread,但IntentService的实例始终只有一个 94 | //Operation 1 95 | Intent startServiceIntent = new Intent("com.test.intentservice"); 96 | Bundle bundle = new Bundle(); 97 | bundle.putString("param", "oper1"); 98 | startServiceIntent.putExtras(bundle); 99 | startService(startServiceIntent); 100 | 101 | //Operation 2 102 | Intent startServiceIntent2 = new Intent("com.test.intentservice"); 103 | Bundle bundle2 = new Bundle(); 104 | bundle2.putString("param", "oper2"); 105 | startServiceIntent2.putExtras(bundle2); 106 | startService(startServiceIntent2); 107 | } 108 | } 109 | ``` 110 | 111 | 最后,别忘了配置Service,因为它继承于Service,所以,它还是一个Service,一定要配置,否则是不起作用的 112 | 113 | ```xml 114 | 115 | 116 | 117 | 118 | 119 | ``` 120 | 121 | 最后来看看执行结果: 122 | 123 | ![img](http://upload-images.jianshu.io/upload_images/4037105-317f5bb26ae43dd3?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 124 | 125 | 从结果可以看到,onCreate方法只执行了一次,而onStartCommand和onStart方法执行了两次,开启了两个Work Thread,这就证实了之前所说的,启动多次,但IntentService的实例只有一个,这跟传统的Service是一样的。Operation1也是先于Operation2打印,并且我让两个操作间停顿了2s,最后是onDestroy销毁了IntentService。 126 | 127 | ### **IntentService 源码分析** 128 | 129 | ```java 130 | @Override 131 | public void onCreate() { 132 | super.onCreate(); 133 | HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 134 | thread.start(); 135 | mServiceLooper = thread.getLooper(); 136 | mServiceHandler = new ServiceHandler(mServiceLooper); 137 | } 138 | ``` 139 | 140 | #### **源码可知:** 141 | 142 | 1)实际上是使用了一个 HandlerThread 来维护线程的, 143 | 144 | 2) HandleThread 中,内部已经维护一个 Looper,这里直接使用 HandlerThread 的 Looper 对象,便于在 IntentService 中去维护消息队列, 145 | 146 | 3)创建的 mServiceHandler 是属于 HandleThread 这个 WorkerThread 的。 147 | 148 | ```java 149 | private final class ServiceHandler extends Handler { 150 | public ServiceHandler(Looper looper) { 151 | super(looper); 152 | } 153 | 154 | @Override 155 | public void handleMessage(Message msg) { 156 | onHandleIntent((Intent)msg.obj); 157 | stopSelf(msg.arg1); 158 | } 159 | } 160 | ``` 161 | 162 | #### **源码可知:** 163 | 164 | 1)直接把消息交给 onHandleIntent() 方法去执行具体的业务逻辑 165 | 166 | 2)执行完成之后,立即调用 stopSelf() 方法停止自己 167 | 168 | 接下来分析start源码 169 | 170 | ```java 171 | @Override 172 | public void onStart(Intent intent, int startId) { 173 | Message msg = mServiceHandler.obtainMessage(); 174 | msg.arg1 = startId; 175 | msg.obj = intent; 176 | mServiceHandler.sendMessage(msg); 177 | } 178 | @Override 179 | public int onStartCommand(Intent intent, int flags, int startId) { 180 | onStart(intent, startId); 181 | return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 182 | } 183 | ``` 184 | 185 | #### 源码可知 186 | 187 | 1)在 onStartCommand() 中直接调用了 onStart() 方法 188 | 189 | 2)而上面 stopSelf() 方法使用的 startId 来停止当前的此次任务服务。 190 | 191 | 3)而 Service 如果被启动多次,就会存在多个 startId ,当所有的 startId 都被停止之后,才会调用 onDestory() 自我销毁。 192 | 193 | 我们在看看HandlerThread启动之后的源码 194 | 195 | ```java 196 | @Override 197 | public void run() { 198 | mTid = Process.myTid(); 199 | Looper.prepare(); 200 | synchronized (this) { 201 | mLooper = Looper.myLooper(); 202 | notifyAll(); 203 | } 204 | Process.setThreadPriority(mPriority); 205 | onLooperPrepared(); 206 | Looper.loop(); 207 | mTid = -1; 208 | } 209 | ``` 210 | 211 | #### **源码可知** 212 | 213 | run方法里面添加了锁,这也解释了为什么多次 start 同一个 IntentService 它会顺序执行,全部执行完成之后,再自我销毁。 -------------------------------------------------------------------------------- /Service/README.md: -------------------------------------------------------------------------------- 1 | ## Service相关面试题 2 | 3 | - [IntentService源码分析](IntentService源码分析.md) 4 | - [Service是否在main thread中执行, service里面是否能执行耗时的操作?](Android面试题-Service.md) 5 | - [Android面试题-Service不死之身](Android面试题-Service不死之身.md) -------------------------------------------------------------------------------- /assets/activity_start_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/activity_start_flow.png -------------------------------------------------------------------------------- /assets/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/wechat.jpg -------------------------------------------------------------------------------- /assets/weixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/weixin.png -------------------------------------------------------------------------------- /assets/支付宝.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/支付宝.jpg -------------------------------------------------------------------------------- /assets/腾讯.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/腾讯.png -------------------------------------------------------------------------------- /assets/腾讯2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/腾讯2.jpg -------------------------------------------------------------------------------- /assets/腾讯3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/assets/腾讯3.jpg -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "JackChan", 3 | "description": "Android面试宝典", 4 | "gitbook": "3.2.3", 5 | "language": "zh-hans", 6 | "title": "Android面试宝典", 7 | "pdf": { 8 | "fontFamily": "等线" 9 | } 10 | } -------------------------------------------------------------------------------- /开发遇到的问题/Context原理分析.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [配套视频](https://v.qq.com/x/page/y0396os8vc6.html) 48 | 49 | ## 谈一下你对Android中的context的理解,在一个应用程序中有多少个context实例? 50 | 51 | ### 1. 什么是Context? 52 | 53 | ![img](http://upload-images.jianshu.io/upload_images/4037105-bf283f5324e5a188.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 54 | 55 | 通过金山词霸解释:上下文环境,什么是环境,这个词只可意会不可言传,为了大家更好的理解,举一个栗子,比如:我想点鸡,我在麦当劳跟服务员说我想点鸡,服务员给端上来一只香喷喷的烤鸡,如下图: 56 | 57 | ![img](http://upload-images.jianshu.io/upload_images/4037105-3f21cf0410b902fd.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 58 | 59 | 但是我换一个环境 ,去红灯区点鸡,妈咪就会给带来一只呆萌可爱的失足少女,如下图: 60 | 61 | ![img](http://upload-images.jianshu.io/upload_images/4037105-24dddb07d9119c2a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 62 | 63 | 这就是环境,一样的东西不同地方,就表示不一样的意思。 64 | 65 | ### Context,中文直译为“上下文”,SDK中对其说明如下: 66 | 67 | Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for 68 | application-level operations such as launching activities, broadcasting and receiving intents, etc 69 | 70 | ### 从上可知一下三点,即: 71 | 72 | - 它描述的是一个应用程序环境的信息,即上下文。 73 | - 该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。 74 | - 通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息 等 75 | 76 | 首先看它们的继承关系 77 | 78 | ![img](http://upload-images.jianshu.io/upload_images/4037105-3f6dfbce58383d95.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 79 | 80 | ### 2. 什么时候创建Context实例 81 | 82 | 熟悉了Context的继承关系后,我们接下来分析应用程序在什么情况需要创建Context对象的?应用程序创建Context实例的情况有如下几种情况: 83 | 84 | 1) 创建Application 对象时, 而且整个App共一个Application对象 85 | 2) 创建Service对象时 86 | 3) 创建Activity对象时 87 | 88 | ### 因此应用程序App共有的Context数目公式为: 89 | 90 | > 总Context实例个数 = Service个数 + Activity个数 + 1(Application对应的Context实例) 91 | 92 | 1、创建Application对象的Context: 93 | 首先新建一个MyApplication并让它继承自Application,然后在AndroidManifest.xml文件中对MyApplication进行指定,如下所示: 94 | 95 | ```xml 96 | 102 | ...... 103 | 104 | ``` 105 | 106 | 指定完成后,当我们的程序启动时Android系统就会创建一个MyApplication的实例,通过如下代码获取到它的实例: 107 | 108 | ```java 109 | public class MainActivity extends Activity { 110 | 111 | @Override 112 | protected void onCreate(Bundle savedInstanceState) { 113 | super.onCreate(savedInstanceState); 114 | setContentView(R.layout.activity_main); 115 | MyApplication myApp = (MyApplication) getApplication(); 116 | Log.d("TAG", "getApplication is " + myApp); 117 | } 118 | 119 | } 120 | ``` 121 | 122 | 可以看到,代码很简单,只需要调用getApplication()方法就能拿到我们自定义的Application的实例了,打印结果如下所示: 123 | 124 | ![img](http://upload-images.jianshu.io/upload_images/4037105-bf6808194c852db6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 125 | 126 | 那么除了getApplication()方法,其实还有一个getApplicationContext()方法,这两个方法看上去好像有点关联,那么它们的区别是什么呢?我们将代码修改一下: 127 | 128 | ```java 129 | public class MainActivity extends Activity { 130 | 131 | @Override 132 | protected void onCreate(Bundle savedInstanceState) { 133 | super.onCreate(savedInstanceState); 134 | setContentView(R.layout.activity_main); 135 | MyApplication myApp = (MyApplication) getApplication(); 136 | Log.d("TAG", "getApplication is " + myApp); 137 | Context appContext = getApplicationContext(); 138 | Log.d("TAG", "getApplicationContext is " + appContext); 139 | } 140 | } 141 | ``` 142 | 143 | 同样,我们把getApplicationContext()的结果打印了出来,现在重新运行代码,结果如下图所示: 144 | 145 | ![img](http://upload-images.jianshu.io/upload_images/4037105-308f49c6b7acc8f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 146 | 147 | 打印出的结果是一样的呀,连后面的内存地址都是相同的,看来它们是同一个对象。其实这个结果也很好理解,Application本身就是一个Context,所以这里获取getApplicationContext()得到的结果就是MyApplication本身的实例。 148 | 149 | 那么有的朋友可能就会问了,既然这两个方法得到的结果都是相同的,那么Android为什么要提供两个功能重复的方法呢?实际上这两个方法在作用域上有比较大的区别。getApplication()方法的语义性非常强,一看就知道是用来获取Application实例的,但是这个方法只有在Activity和Service中才能调用的到。那么也许在绝大多数情况下我们都是在Activity或者Service中使用Application的,但是如果在一些其它的场景,比如BroadcastReceiver中也想获得Application的实例,这时就可以借助getApplicationContext()方法了,如下所示: 150 | 151 | ```java 152 | public class MyReceiver extends BroadcastReceiver { 153 | 154 | @Override 155 | public void onReceive(Context context, Intent intent) { 156 | MyApplication myApp = (MyApplication) context.getApplicationContext(); 157 | Log.d("TAG", "myApp is " + myApp); 158 | } 159 | 160 | } 161 | ``` 162 | 163 | 也就是说,getApplicationContext()方法的作用域会更广一些,任何一个Context的实例,只要调用getApplicationContext()方法都可以拿到我们的Application对象。 164 | 165 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 166 | 167 | 微信公众号名称:Android干货程序员 168 | 169 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /开发遇到的问题/README.md: -------------------------------------------------------------------------------- 1 | ## 与开发相关面试题 2 | 3 | - [迭代开发的时候如何向前兼容新旧接口?](迭代开发的时候如何向前兼容新旧接口?.md) 4 | - [手把手教你如何解决as jar包冲突](手把手教你如何解决as jar包冲突.md) 5 | - [Context原理分析](Context原理分析.md) 6 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](终极解决ViewPager.setCurrentItem中间页面过多解决方案.md) 7 | - [解决字体适配](解决字体适配.md) 8 | - [软键盘顶出去解决方案](软键盘顶出去解决方案.md) 9 | - [机型适配之痛](机型适配之痛.md) -------------------------------------------------------------------------------- /开发遇到的问题/ViewPager和Fragment使用过程中会遇到哪些问题.md: -------------------------------------------------------------------------------- 1 | **ViewPager和Fragment使用过程中会遇到哪些问题** 2 | 3 | ### 1. 适配器的选择 4 | 5 | 使用ViewPager加载多个Fragment时,我一般选择FragmentPagerAdapter。 6 | 需要大家注意: 7 | FragmentPagerAdapter:该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的场景 8 | 但是,如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,这时候,我们选择怎么是的适配器呢? 9 | 10 | 应该使用FragmentStatePagerAdapter 11 | 12 | FragmentStatePagerAdapter:会把已经创建的Fragment进行保存。会保持Fragment的状态 13 | 通过源码分析发现: 14 | FragmentStatePagerAdapter这个类抽象出了一个getItem()方法,用于创建对应的Fragment 15 | 而FragmentStatePagerAdapter的.instantiateItem()方法实现中,调用了getIitem()方法。 16 | 调用该instantiateItem()方法时,判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach(); 17 | 如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。 18 | FragmentStatePagerAdapter会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法。 19 | 20 | ### 2. Fragment数据的缓存 21 | 22 | Fragment在初始化View对象,把该对象作为一个成员变量进行保存。 23 | 再一次初始化Fragment对应的View对象时,判断当前成员变量View对象是否为空。 24 | 如果为空,创建新的View对象,否则,不在创建。这样就可以做到对Fragemnt进行数据缓存 25 | 26 | 这样做的好处:避免了每次加载Fragment都要重新创建View,加载数据了。提高了性能,以及减少了内存的开销。 27 | 28 | ### 3. ViewPager预加载 29 | 30 | 我们知道,系统的ViewPager默认提供预加载机制。但是,根据业务需要,取消掉对应的预加载机制。 31 | 可以这样做:替换掉系统原生的Viewpager类。将该类中的一个变量mOffscreenPageLimit 设置为0,不进行预加载 32 | 33 | ### 4. Fragment嵌套Fragment 34 | 35 | 在Fragment中嵌套Fragment时,一定要使用getChildFragmentManager(); 36 | 37 | 否则,会在ViewPager中出现fragment不会加载的情况,即fragment出现空白页的情况。 -------------------------------------------------------------------------------- /开发遇到的问题/手把手教你如何解决as jar包冲突.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | 第一:当出现这个错误就是jar包冲突。 46 | 47 | ![img](http://upload-images.jianshu.io/upload_images/4037105-9147f9c33825f794.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 48 | 49 | 第二:解决办法,双击Shift搜索,会发现如下图片: 50 | 51 | ![img](http://upload-images.jianshu.io/upload_images/4037105-01ec162adcd79502.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 52 | 53 | 搜索你会发现我的项目里面添加了okhttp3.6,bomb里面也添加了okhttp3.3.1,这时候系统就不知道该用哪个jar冲突了。 54 | 55 | 第三:打开项目的扩展库,如下图展示: 56 | 57 | ![img](http://upload-images.jianshu.io/upload_images/4037105-d952e4f45f66ce3d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 58 | 59 | 会发现bomb自带了okhttp的jar包,如图片展示。 60 | 61 | ![img](http://upload-images.jianshu.io/upload_images/4037105-cee4021279d743d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 62 | 63 | 我的项目也再带okhttp的jar包,如图片展示。 64 | 65 | ![img](http://upload-images.jianshu.io/upload_images/4037105-c05678f43cb13f4d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 66 | 67 | 第四:找到我的build.gradle文件,去掉刚刚冲突的jar包,如下展示: 68 | 69 | ```gradle 70 | //bmob-sdk:Bmob的android sdk包,包含了Bmob的数据存储、文件等服务,以下是最新的bmob-sdk: 71 | compile ('cn.bmob.android:bmob-sdk:3.5.5'){ // gson-2.6.2 72 | exclude group: 'com.squareup.okhttp3' 73 | exclude group: 'com.squareup.okio' 74 | exclude group: 'com.google.code.gson' 75 | // exclude(module: 'gson') // 防止版本冲突 76 | } 77 | 78 | // 网络加载 79 | compile ('com.squareup.okhttp3:okhttp:3.6.0'){ 80 | exclude group: 'com.squareup.okhttp3' 81 | exclude group: 'com.squareup.okio' 82 | } 83 | ``` 84 | 85 | 至此解决冲突。 86 | 87 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 88 | - 微信公众号名称:Android干货程序员 89 | 90 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /开发遇到的问题/终极解决ViewPager.setCurrentItem中间页面过多解决方案.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [ViewPager.setCurrentItem的bug演示一](https://v.qq.com/x/page/n0501ylwqx1.html) 48 | - [ViewPager.setCurrentItem解决方案二](https://v.qq.com/x/page/g05012qi6hs.html) 49 | 50 | 今天做项目用ViewPager.setCurrentItem 方法,如果两个页面相聚比较远,就会闪瞎我的钛合金双眼,中间切换大概20个页面,如下所示: 51 | 52 | ![img](http://upload-images.jianshu.io/upload_images/4037105-bab7127dbfb0d444?imageMogr2/auto-orient/strip) 53 | 54 | setCurrentItem第二个参数设置false,四不四很简单,直接使用如下代码: 55 | 56 | ``` 57 | ViewPager.setCurrentItem(position,false); 58 | ``` 59 | 60 | 很不幸的是,使用上面的代码会出现如下效果,扎心了老铁: 61 | 62 | ![img](http://upload-images.jianshu.io/upload_images/4037105-5dc7bf8e931596ce?imageMogr2/auto-orient/strip) 63 | 64 | 从第一题点击切换到第十八题,你会发现页面显示空白,如果从第十个页面切换到第十五个页面没事,平时大家估计没有发现这个bug,一般我们使用ViewPager都是底下5个tab页面,从第一个切换到第五个没事,之前我也以为把第二个参数设置false就行,今天才发现,原来如果当页面比较少的时候,大概十个以内,一般没有问题,如果超过十个页面切换就会出现空白,加载不了数据,扎心了,提出解决方案吧,ViewPager滑动使用的是Scroll,咱们把Scroll的滑动时间duration 设置为0就行。 65 | 66 | ### **自定义一个Scroll类,用于控制ViewPager滑动速度:** 67 | 68 | ```java 69 | public class MScroller extends Scroller { 70 | 71 | private static final Interpolator sInterpolator = new Interpolator() { 72 | public float getInterpolation(float t) { 73 | t -= 1.0f; 74 | return t * t * t * t * t + 1.0f; 75 | } 76 | }; 77 | 78 | 79 | public boolean noDuration; 80 | 81 | public void setNoDuration(boolean noDuration) { 82 | this.noDuration = noDuration; 83 | } 84 | 85 | public MScroller(Context context) { 86 | this(context,sInterpolator); 87 | } 88 | 89 | public MScroller(Context context, Interpolator interpolator) { 90 | super(context, interpolator); 91 | } 92 | 93 | @Override 94 | public void startScroll(int startX, int startY, int dx, int dy, int duration) { 95 | if(noDuration) 96 | //界面滑动不需要时间间隔 97 | super.startScroll(startX, startY, dx, dy, 0); 98 | else 99 | super.startScroll(startX, startY, dx, dy,duration); 100 | } 101 | } 102 | ``` 103 | 104 | #### **上面代码可知:** 105 | 106 | 1)动态判断页面是否需要滑动,如果不需要滑动,设置滑动时间为0; 107 | 108 | ### **为方便使用,定义一个辅助类** 109 | 110 | ```java 111 | public class ViewPageHelper { 112 | ViewPager viewPager; 113 | 114 | MScroller scroller; 115 | 116 | public ViewPageHelper(ViewPager viewPager) { 117 | this.viewPager = viewPager; 118 | init(); 119 | } 120 | 121 | public void setCurrentItem(int item){ 122 | setCurrentItem(item,true); 123 | } 124 | 125 | public MScroller getScroller() { 126 | return scroller; 127 | } 128 | 129 | 130 | public void setCurrentItem(int item, boolean somoth){ 131 | int current=viewPager.getCurrentItem(); 132 | //如果页面相隔大于1,就设置页面切换的动画的时间为0 133 | if(Math.abs(current-item)>1){ 134 | scroller.setNoDuration(true); 135 | viewPager.setCurrentItem(item,somoth); 136 | scroller.setNoDuration(false); 137 | }else{ 138 | scroller.setNoDuration(false); 139 | viewPager.setCurrentItem(item,somoth); 140 | } 141 | } 142 | 143 | private void init(){ 144 | scroller=new MScroller(viewPager.getContext()); 145 | Classcl=ViewPager.class; 146 | try { 147 | Field field=cl.getDeclaredField("mScroller"); 148 | field.setAccessible(true); 149 | //利用反射设置mScroller域为自己定义的MScroller 150 | field.set(viewPager,scroller); 151 | } catch (NoSuchFieldException e) { 152 | e.printStackTrace(); 153 | }catch (IllegalAccessException e){ 154 | e.printStackTrace(); 155 | } 156 | } 157 | 158 | } 159 | ``` 160 | 161 | #### **由上面代码可知:** 162 | 163 | 1)Math.abs(current-item)>1 ,通过数学函数判断页面相隔大于1,就设置页面切换的动画的时间为0。 164 | 165 | 2)这样每次设置页面的时候,通过 helper 就可以自动选择是否有时间间隔了。 166 | 167 | 3)但是这样有点麻烦,每次还要手动改,而且使用TabLayout或者ViewPagerIndicator的话,它会自动调用ViewPager的方法,无法使用Helper,所以可以采用自定一个ViewPager,代码如下: 168 | 169 | ```java 170 | public class SuperViewPager extends ViewPager { 171 | 172 | 173 | private ViewPageHelper helper; 174 | 175 | public SuperViewPager(Context context) { 176 | this(context,null); 177 | } 178 | 179 | public SuperViewPager(Context context, AttributeSet attrs) { 180 | super(context, attrs); 181 | helper=new ViewPageHelper(this); 182 | 183 | } 184 | 185 | @Override 186 | public void setCurrentItem(int item) { 187 | setCurrentItem(item,true); 188 | } 189 | 190 | @Override 191 | public void setCurrentItem(int item, boolean smoothScroll) { 192 | MScroller scroller=helper.getScroller(); 193 | if(Math.abs(getCurrentItem()-item)>1){ 194 | scroller.setNoDuration(true); 195 | super.setCurrentItem(item, smoothScroll); 196 | scroller.setNoDuration(false); 197 | }else{ 198 | scroller.setNoDuration(false); 199 | super.setCurrentItem(item, smoothScroll); 200 | } 201 | } 202 | } 203 | ``` 204 | 205 | 至此完美解决了,ViewPager.setCurrentItem切换页面,效果如下: 206 | 207 | ![img](http://upload-images.jianshu.io/upload_images/4037105-b2f5486c91c65eae?imageMogr2/auto-orient/strip) 208 | 209 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 210 | - 微信公众号名称:Android干货程序员 211 | 212 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /开发遇到的问题/解决字体适配.md: -------------------------------------------------------------------------------- 1 | ## [Android面试题-解决字体适配](http://www.jianshu.com/p/33d499170e25) 2 | 3 | ![img](http://upload-images.jianshu.io/upload_images/4037105-e301f4b8dd0e65c0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 4 | 5 | ![img](http://upload-images.jianshu.io/upload_images/4037105-90e9a7ed7ea4a2d3?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 6 | 7 | 做个简单的例子,先验证一下: 8 | 9 | 同样的布局代码 10 | 11 | ```xml 12 | 17 | 18 | 23 | ``` 24 | 25 | 调节设置中显示字体大小 26 | 27 | ![img](http://upload-images.jianshu.io/upload_images/4037105-9c7b06ffd4edeaf2?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 28 | 29 | 运行后显示样式 30 | 31 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ce4446f4d89bf902?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 32 | 33 | 回到标题要解决的问题,如果要像微信一样,所有字体都不允许随系统调节而发生大小变化,要怎么办呢?利用Android的Configuration类中的fontScale属性,其默认值为1,会随系统调节字体大小而发生变化,如果我们强制让其等于默认值,就可以实现字体不随调节改变,在工程的Application或BaseActivity中添加下面的代码: 34 | 35 | ```java 36 | @Override 37 | public void onConfigurationChanged(Configuration newConfig) { 38 | if (newConfig.fontScale != 1)//非默认值 39 | getResources(); 40 | super.onConfigurationChanged(newConfig); 41 | } 42 | 43 | @Override 44 | public Resources getResources() { 45 | Resources res = super.getResources(); 46 | if (res.getConfiguration().fontScale != 1) {//非默认值 47 | Configuration newConfig = new Configuration(); 48 | newConfig.setToDefaults();//设置默认 49 | res.updateConfiguration(newConfig, res.getDisplayMetrics()); 50 | } 51 | return res; 52 | } 53 | ``` 54 | 55 | 总结,两种方案解决这个问题: 56 | 一是布局宽高固定的情况下,字体单位改用dp表示; 57 | 二是通过3中的代码设置应用不能随系统调节,在检测到fontScale属性不为默认值1的情况下,强行进行改变。 -------------------------------------------------------------------------------- /开发遇到的问题/软键盘顶出去解决方案.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | - [深刻剖析activity启动模式(一)](http://www.jianshu.com/p/b33fd8c550bf) 13 | - [深刻剖析activity启动模式(二)](http://www.jianshu.com/p/e1ea9e542112) 14 | - [深刻剖析activity启动模式(三)](http://www.jianshu.com/p/d13e3d552d4b) 15 | - [service里面startActivity抛异常?activity不会](http://www.jianshu.com/p/16e880ceb3a4) 16 | 17 | ### 与XMPP相关面试题 18 | 19 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 20 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 21 | 22 | ### 与性能优化相关面试题 23 | 24 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 25 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 26 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 27 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 28 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 29 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 30 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 31 | 32 | ### 与登录相关面试题 33 | 34 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 35 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 36 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 37 | 38 | ### 与开发相关面试题 39 | 40 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 41 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 42 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 43 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 44 | - [字体适配](http://www.jianshu.com/p/33d499170e25) 45 | - [软键盘顶出去解决方案](http://www.jianshu.com/p/640bac6f58ab)与人事相关面试题 46 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 47 | 48 | 错误的打开方式 49 | 50 | ![img](http://upload-images.jianshu.io/upload_images/4037105-d3bae424787347e2.gif?imageMogr2/auto-orient/strip) 51 | 52 | 错误的打开姿势.gif 53 | 54 | 仔细观察会发现,当软键盘弹出时 **background、recyclerview、toolbar** 被**软键盘**顶上去了!这样的交互简直不能忍,对用户来说也非常突兀。 55 | 正确的打开方式 56 | 57 | ![img](http://upload-images.jianshu.io/upload_images/4037105-f64f01282733e751.gif?imageMogr2/auto-orient/strip) 58 | 59 | 正确的打开姿势.gif 60 | 61 | 软键盘弹出只是遮盖了 **background** 一部分,**background** 没有被**压缩**。 62 | 63 | 实现 64 | 65 | 1. AndroidMainifest.xml 配置文件 66 | 67 | ```xml 68 | 71 | ``` 72 | 73 | 非透明状态栏下使用adjustResize和adjustPan,或是透明状态栏下使用`fitsSystemWindows=true`属性 74 | 75 | 主要实现方法: 在AndroidManifest.xml对应的Activity里添加`windowSoftInputMode=”adjustPan”`或是`android:windowSoftInputMode=”adjustResize”`属性 76 | 77 | 推荐一篇软键盘很好的文章:[http://blog.csdn.net/smileiam/article/details/69055963](http://blog.csdn.net/smileiam/article/details/69055963) 78 | 79 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 80 | - 微信公众号名称:Android干货程序员 81 | 82 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /开发遇到的问题/迭代开发的时候如何向前兼容新旧接口?.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频。。 46 | 47 | - [配套视频](https://v.qq.com/x/page/a0395pv28zm.html) 48 | 49 | ### 迭代开发的时候如何向前兼容新旧接口? 50 | 51 | 设计服务器接口时,每一个接口,都带版本号。比如用户登陆接口第 1 版为 52 | 53 | ``` 54 | /1/user/login 55 | ``` 56 | 57 | 返回 Json 数据。数据结构改动后,假如 Json 数据只是增加字段,这时接口不用修改。当登陆接口改动太大,会删除或者修改字段。就递增版本号,新添接口: 58 | 59 | ``` 60 | /2/user/login 61 | ``` 62 | 63 | 旧的 /1/user/login 接口需要保留,这时旧的客户端使用 /1/user/login,而新的客户端使用 /2/user/login。 64 | 65 | 在服务端 /1/user/login 和 /2/user/login 进行重构,某些地方调用相同的代码。两个接口并存一段时间后,比如过了 3 个月。估计旧的客户端差不多都升级到新的了,这时旧的 /1/user/login 接口就可以不再维护,直接返回错误码。 66 | 67 | 比如开源中国开发也是如此,开源中国API接口如下: 68 | 69 | ![img](http://upload-images.jianshu.io/upload_images/4037105-4fa3bfc810e0305c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 70 | 71 | ![img](http://upload-images.jianshu.io/upload_images/4037105-7043d98ff097e97f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 72 | 73 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 74 | 75 | 微信公众号名称:Android干货程序员 76 | 77 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/Android应用UI性能分析.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频。 46 | 47 | - [HierarchyViewer配套视频](https://v.qq.com/x/page/y0393sa0jlp.html) 48 | - [Lint配套视频](https://v.qq.com/x/page/d039381wbas.html) 49 | - [内存抖动现象配套视频](https://v.qq.com/x/page/x0393gf7qp6.html)12-如何对android应用进行内存性能分析 50 | 51 | ### Android应用UI性能分析 52 | 53 | 在使用App时会发现有些界面启动卡顿、动画不流畅、列表等滑动时也会卡顿出现这种情况,可以考虑对UI性能分析。 54 | 55 | > 首先要清楚卡顿的原因,有以下几种情况: 56 | 57 | - 人为在UI线程中做轻微耗时操作,导致UI线程卡顿 58 | 59 | - 布局Layout过于复杂,无法在16ms内完成渲染 60 | 61 | - 同一时间动画执行的次数过多,导致CPU或GPU负载过重 62 | 63 | - View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重 64 | 65 | - View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染 66 | 67 | - 内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作 68 | 69 | - 冗余资源及逻辑等导致加载和执行缓慢 70 | 71 | - 臭名昭著的ANR 72 | 73 | ### 如何分析? 74 | 75 | > 分析UI卡顿我们一般都借助工具,通过工具一般都可以直观的分析出问题原因,从而反推寻求优化方案,具体如下细说各种强大的工具 76 | 77 | ### 使用HierarchyViewer分析UI性能 78 | 79 | 我们可以通过SDK提供的工具HierarchyViewer来进行UI布局复杂程度及冗余等分析 80 | 通过命令启动HierarchyViewer 81 | 82 | ![img](http://upload-images.jianshu.io/upload_images/4037105-913938b7dd911784.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 83 | 84 | 接下来Hierarchy window窗口打开: 85 | 86 | ![img](http://upload-images.jianshu.io/upload_images/4037105-750650883b206a5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 87 | 88 | 一个Activity的View树,通过这个树可以分析出View嵌套的冗余层级,以及每个View在绘制的使用时长也有表示。 89 | 90 | ### 使用Lint进行资源及冗余UI布局等优化 91 | 92 | 冗余资源及逻辑等也可能会导致加载和执行缓慢,这可以使用Link工具,来发现优化这些问题的 93 | 94 | 在Android Studio 1.4版本中使用Lint最简单的办法: 95 | 就是将鼠标放在代码区点击右键->Analyze->Inspect Code–>界面选择你要检测的模块->点击确认开始检测,等待一下后会发现如下结果: 96 | 97 | ![img](http://upload-images.jianshu.io/upload_images/4037105-84f3df4cfd1d4c07.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 98 | 99 | 如果存在冗余的UI层级嵌套,会进行高亮显示, 我们根据提示可以点击跳进去进行优化处理掉的。 100 | 101 | ### 使用Memory监测及GC打印与Allocation Tracker进行UI卡顿分析 102 | 103 | 由于Android系统会依据内存中不同的内存数据类型分别执行不同的GC操作,常见应用开发中导致GC频繁执行的原因主要可能是因为短时间内有大量频繁的对象创建与释放操作,也就是俗称的内存抖动现象,或者短时间内已经存在大量内存暂用介于阈值边缘,接着每当有新对象创建时都会导致超越阈值触发GC操作 104 | 105 | ### 如何查看? 106 | 107 | #### Android Studio 工具提供内存查看器: 108 | 109 | ![img](http://upload-images.jianshu.io/upload_images/4037105-26fcbce199c511c8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 110 | 111 | #### 根据内存抖动现象,查看log日志进行分析: 112 | 113 | ![img](http://upload-images.jianshu.io/upload_images/4037105-64af051f5b7d76da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 114 | 115 | > 如何看到,这种不停的大面积打印GC导致所有线程暂停的操作必定会导致UI视觉的卡顿,所以我们要避免此类问题的出现,具体的常见优化方式如下: 116 | 117 | - 检查代码,尽量避免有些频繁触发的逻辑方法中存在大量对象分配 118 | - 尽量避免在多次for循环中频繁分配对象 119 | - 避免在自定义View的onDraw()方法中执行复杂的操作及创建对象(譬如Paint的实例化操作不要写在onDraw()方法中等) 120 | - 对于并发下载等类似逻辑的实现尽量避免多次创建线程对象,而是交给线程池处理。 121 | 122 | 有了上面说明GC导致的性能后我们就该定位分析问题了, 123 | 我们可以通过运行DDMS->Allocation Tracker标签打开一个新窗口,然后点击Start Tracing按钮,接着运行你想分析的代码,运行完毕后点击Get Allocations按钮就能够看见一个已分配对象的列表,如下: 124 | 125 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8e16375acbfadf55.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 126 | 127 | 根据内存分配情况,进行优化。 128 | 129 | 写篇文章和录制视频从选题,思考,组织,写作,编辑至少需要一个多小时,而您点赞和转发只需要0.1秒,就可以带给我更大的动力,何乐而不为呢? 130 | 131 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 132 | 133 | 微信公众号名称:Android干货程序员 134 | 135 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/README.md: -------------------------------------------------------------------------------- 1 | ## 与性能优化相关面试题 2 | 3 | - [内存泄漏和内存溢出区别](与性能优化相关试题一.md) 4 | - [UI优化和线程池实现原理](与性能优化相关试题二.md) 5 | - [代码优化](与性能优化相关试题三.md) 6 | - [Android应用UI性能分析](Android应用UI性能分析.md) 7 | - [内存泄漏监测](内存泄漏监测.md) 8 | - [App应用启动分析与优化](App应用启动分析与优化.md) 9 | - [与IPC机制相关面试题](与IPC机制相关面试题.md) -------------------------------------------------------------------------------- /性能优化/与IPC机制相关面试题.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 与人事相关面试题 46 | 47 | - [人事面试宝典](http://blog.csdn.net/mwq384807683/article/details/71435960) 48 | 49 | > 现在三四月份,金三银四最好找工作时间,为方便各位找工作,特意收集100道android各个方面的面试题,并且会一一录制视频分享给大家方便大家找工作,面试题分类如下; 50 | 51 | ![img](http://upload-images.jianshu.io/upload_images/4037105-4437ab22b7af3cc8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 52 | 53 | ![img](http://upload-images.jianshu.io/upload_images/4037105-22abf62d3d9f68a5.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 54 | 55 | ![img](http://upload-images.jianshu.io/upload_images/4037105-6838fa267298201a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 56 | 57 | ![img](http://upload-images.jianshu.io/upload_images/4037105-c8d1161109029383.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 58 | 59 | ### 本文配套视频 60 | 61 | - [配套视频](https://v.qq.com/x/page/a03916l1n7h.html) 62 | - [配套视频](https://v.qq.com/x/page/m0391pnoyl7.html) 63 | - [配套视频](https://v.qq.com/x/page/t0391b2gjm5.html) 64 | - [配套视频](https://v.qq.com/x/page/v0391vx3ynb.html) 65 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 66 | 67 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 68 | 69 | ## 1- Davik进程、linux进程、线程之间的区别? 70 | 71 | ### Linux进程: 72 | 73 | - Linux进程,它有独立的内核堆栈和独立的存储空间,它是操作系统中资源分配和调度的最小单位。 74 | - Linux操作系统会以进程为单位,分配系统资源,给程序进行调度。 75 | - Linux操作系统在执行一个程序时,它会创建一个进程,来执行应用程序,并且伴随着资源的分配和释放。 76 | 77 | ### Davik进程: 78 | 79 | - Dalvik虚拟机运行在Linux操作系统之上。 80 | - Davik进程就是Linux操作系统中的一个进程,属于linux进程 81 | - 每个Android应用程序进程都有一个Dalvik虚拟机实例。这样做得好处是Android应用程序进程之间不会互相影响,也就是说,一个Android应用程序进程的意外终止,不会影响到其他的应用程序进程的正常运行。 82 | 83 | ### 线程: 84 | 85 | - 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。 86 | - 线程自己基本上不拥有系统资源,在运行时,只需要必不可少的资源(如程序计数器,一组寄存器和栈)。 87 | - 线程与同属一个进程的其他的线程共享进程所拥有的全部资源。 88 | 89 | ### 三者之间的联系: 90 | 91 | - Davik进程就是Linux操作系统的一个进程。 92 | - 线程就是进程的一个实体,线程是进程的一部分。一个进程中可以提供多个线程执行控制。 93 | 94 | ### 进程和线程的区别: 95 | 96 | - 一个程序至少有一个进程,一个进程至少有一个线程. 97 | - 线程的划分尺度小于进程,使得多线程程序的并发性高。 98 | - 进程在执行过程中拥有独立的内存单元,而多个线程共享内存(同属一个进程),从而极大地提高了程序的运行效率。 99 | - 每个独立的进程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 100 | - 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。 101 | 102 | # 2-Android 中进程与进程之间如何通信? 103 | 104 | > aidl机制进程间通信 105 | > AIDL: (Android Interface definition language的缩写)它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口 106 | 107 | AIDL进程间通讯的原理: 108 | 通过编写aidl文件来定义进程间通信接口。 109 | 编译后会自动生成响应的java文件 110 | 服务器将接口的具体实现写在Stub中,用iBinder对象传递给客户端, 111 | 客户端bindService的时候,用asInterface的形式将iBinder还原成接口,再调用其接口中的方法来实现通信。 112 | 113 | ### 使用Messenger实现进程间通信 114 | 115 | > Messenger是基于AIDL实现的。 116 | > AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。 117 | 118 | - 需要大家注意: 119 | - 区别Messenger和Message。 120 | - Message是消息,承载了要传递的数据。 121 | - Messenger是信使,可以发送消息。并且Messenger对象可以通过getBinder方法获取一个Ibinder对象。 122 | 123 | ### Messenger实现原理: 124 | 125 | > 服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。 126 | > 双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。 127 | 128 | ### 使用Messenger实现进程间通信方法如下: 129 | 130 | - 首先A应用提供一个Service,创建一个Messenger对象,在onBinder方法里返回messenger.getBinder()生成的IBinder对象; 131 | 然后在B应用绑定该Service,在ServiceConnection的onServiceConnected方法获取到IBinder对象; 132 | - 最后在B应用使用获取到的binder对象构造出一个新的Messenger对象,使用该Messenger对象的send方法发送的Message数据,都将被Service里的Messenger对象handlerMessage方法接收到。 133 | 134 | ### 内容提供者ContentProvider实现进程间通信 135 | 136 | 系统四大组件之一,底层也是Binder实现,主要用来为其他APP提供数据。 137 | 138 | > 自定义的ContentProvider为外界进程访问的时候, 139 | > 需要在注册时要提供authorities属性,应用需要访问的时候将属性包装成Uri.parse("content://authorities")。 140 | 141 | - 然后实现: 142 | ContentProvider的中query,delete,insert等相关方法,进行数据的操作。 143 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 144 | 145 | 微信公众号名称:Android干货程序员 146 | 147 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/与性能优化相关试题一.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [配套视频](https://v.qq.com/x/page/n0391if5dtb.html) 48 | - [配套视频](https://v.qq.com/x/page/q03917e4zk5.html) 49 | - [配套视频](https://v.qq.com/x/page/j03927ullcj.html) 50 | 51 | ### 9-内存泄漏和内存溢出分别是什么?它们有什么关系? 52 | 53 | - 内存泄露是指保存了不可能再被访问的变量引用,导致垃圾回收器无法回收内存。 54 | 也就是说:在Java中有些对象的生命周期是有限的,当它们完成了特定的逻辑后将会被垃圾回收;但是,如果在对象的生命周期本来该被垃圾回收时这个对象还被别的对象所持有引用,那就会导致内存泄漏 55 | 56 | 57 | - 内存溢出是指虚拟机内存耗尽,无法为新对象分配内存,导致引用崩溃。典型的情况为加载多张大图,导致内存耗尽。 58 | 59 | ![img](http://upload-images.jianshu.io/upload_images/4037105-edf3c4ee63ad3c13.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 60 | 61 | - 当某个界面存在内存泄露,反复进入该界面,将导致一直有新对象创建但是无法回收,最终内存耗尽,产生内存溢出。 62 | 63 | ### 10-什么情况下会导致内存泄漏 64 | 65 | - 资源释放问题 66 | 程序代码的问题,长期保持某些资源,如Context、Cursor、IO流的引用,资源得不到释放造成内存泄露。 67 | - 对象内存过大问题 68 | 保存了多个耗用内存过大的对象(如Bitmap、XML文件),造成内存超出限制。 69 | - static关键字的使用问题 70 | static是Java中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果用它来引用一些资源耗费过多的实例(Context的情况最多),这时就要谨慎对待了。 71 | 针对static的解决方案: 72 | 1) 应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。 73 | 2) Context尽量使用ApplicationContext,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。 74 | 3) 使用WeakReference代替强引用。比如可以使用WeakReference mContextRef; 75 | - 线程导致内存溢出 76 | 线程产生内存泄露的主要原因在于线程生命周期的不可控。 77 | 针对这种线程导致的内存泄露问题的解决方案: 78 | - 将线程的内部类,改为静态内部类(因为非静态内部类拥有外部类对象的强引用,而静态类则不拥有)。 79 | - 在线程内部采用弱引用保存Context引用。 80 | 81 | 82 | - 查询数据库没有关闭cursor 83 | 程序中经常会进行查询数据库的操作,但是经常会有使用完毕Cursor后没有关闭的情况。如果我们的查询结果集比较小,对内存的消耗不容易被发现,只有在常时间大量操作的情况下才会出现内存问题,这样就会给以后的测试和问题排查带来困难和风险。 84 | 85 | 86 | - 构造Adapter没有复用convertview 87 | 在使用ListView的时候通常会使用Adapter,那么我们应该尽可能的使用ConvertView。 88 | 为什么要复用convertView? 89 | 当convertView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。 90 | 91 | 92 | - Bitmap不再使用时没有调用recycle()释放内存 93 | 94 | 有时我们会手工的操作Bitmap对象,如果一个Bitmap对象比较占内存,当它不再被使用的时候,可以调用Bitmap.recycle()方法回收此对象的像素所占用的内存,但这不是必须的,视情况而定。 95 | 96 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 97 | 98 | 微信公众号名称:Android干货程序员 99 | 100 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/与性能优化相关试题三.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [String字符串优化配套视频](https://v.qq.com/x/page/k0393ataw3l.html) 48 | - [其他优化配套视频](https://v.qq.com/x/page/j0393gm2p7j.html) 49 | 50 | ## String字符串优化 51 | 52 | 最常见的例子就是当你要频繁操作一个字符串时,使用StringBuffer代替String。 53 | 还比如:使用int数组而不是Integer数组。 54 | 避免创建短命的临时对象,减少对象的创建就能减少垃圾收集,进而减少对用户体验的影响。 55 | 56 | ## ListView优化 57 | 58 | 1. Item布局,层级越少越好,使用hierarchyview工具查看优化。 59 | 2. 复用convertView 60 | 3. 使用ViewHolder 61 | 4. item中有图片时,异步加载 62 | 5. 快速滑动时,不加载图片 63 | 6. item中有图片时,应对图片进行适当压缩 64 | 7. 实现数据的分页加载 65 | 66 | ## 减少不必要的全局变量 67 | 68 | 尽量避免static成员变量引用资源耗费过多的实例,比如Context。 69 | 因为Context的引用超过它本身的生命周期,会导致Context泄漏。所以尽量使用Application这种Context类型。 70 | 你可以通过调用Context.getApplicationContext()或 Activity.getApplication()轻松得到Application对象。 71 | 72 | ## Cursor(游标)回收 73 | 74 | Cursor是Android查询数据后得到的一个管理数据集合的类,在使用结束以后。应该保证Cursor占用的内存被及时的释放掉,而不是等待GC来处理。并且Android明显是倾向于编程者手动的将Cursor close掉,因为在源代码中我们发现,如果等到垃圾回收器来回收时,会给用户以错误提示。 75 | 76 | ## Receiver(接收器)回收 77 | 78 | 调用registerReceiver()后未调用unregisterReceiver(). 79 | 当我们Activity中使用了registerReceiver()方法注册了BroadcastReceiver,一定要在Activity的生命周期内调用unregisterReceiver()方法取消注册 80 | 也就是说registerReceiver()和unregisterReceiver()方法一定要成对出现,通常我们可以重写Activity的onDestory()方法,在onDestory里进行unregisterReceiver操作 81 | 82 | ## Stream/File(流/文件)回收 83 | 84 | 主要针对各种流,文件资源等等如: 85 | InputStream/OutputStream,SQLiteOpenHelper,SQLiteDatabase,Cursor,文件,I/O,Bitmap图片等操作等都应该记得显示关闭。 86 | 87 | ## 避免内部Getters/Setters 88 | 89 | 在Android中,虚方法调用的代价比直接字段访问高昂许多。通常根据面向对象语言的实践,在公共接口中使用Getters和Setters是有道理的,但在一个字段经常被访问的类中宜采用直接访问。 90 | for循环 91 | 访问成员变量比访问本地变量慢得多,如下面一段代码: 92 | 93 | ``` 94 | for(int i =0; i < this.mCount; i++) {} 95 | ``` 96 | 97 | 永远不要在for的第二个条件中调用任何方法,如下面一段代码: 98 | 99 | ``` 100 | for(int i =0; i < this.getCount(); i++) {} 101 | ``` 102 | 103 | 对上面两个例子最好改为: 104 | 105 | ``` 106 | int count = this.mCount; / int count = this.getCount(); 107 | for(int i =0; i < count; i++) {} 108 | ``` 109 | 110 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 111 | 112 | 微信公众号名称:Android干货程序员 113 | 114 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/与性能优化相关试题二.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [配套视频](https://v.qq.com/x/page/w0392bn6wto.html) 48 | - [配套视频](https://v.qq.com/x/page/j0393ytx9ob.html) 49 | - [线程池原理配套视频](https://v.qq.com/x/page/u0393izwfut.html) 50 | 51 | 11-说一下如何对Android内存优化上集? 52 | 53 | ## Bitmap OOM(图片优化) 54 | 55 | ### 1. 图片处理 56 | 57 | #### a. 等比缩放 58 | 59 | ![img](http://upload-images.jianshu.io/upload_images/4037105-82ef6ff37b935245.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 60 | 61 | 以上代码可以优化内存溢出,但它只是改变图片大小,并不能彻底解决内存溢出。 62 | 63 | #### b. 对图片采用软引用,及时地进行recyle()操作 64 | 65 | ![img](http://upload-images.jianshu.io/upload_images/4037105-89cce346d56154a0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 66 | 67 | #### c. 设置图片解码格式 68 | 69 | ```java 70 | BitmapFactory.Options options = new BitmapFactory.Options(); 71 | options.inPreferredConfig = Bitmap.Config.ARGB_4444; 72 | ``` 73 | 74 | #### d. 加载部分图片 75 | 76 | ![img](http://upload-images.jianshu.io/upload_images/4037105-5cfa36fe83a5a2e1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 77 | 78 | #### 2. 图片的缓存 79 | 80 | a) 网络缓存 81 | b) 内存缓存 82 | c) 磁盘缓存 83 | 84 | #### 3. 使用加载图片框架处理图片,如专业处理加载图片的ImageLoader,glide,picasso等图片加载框架。 85 | 86 | 通过以上方式可以解决图片OOM异常 87 | 88 | ## UI Review(UI优化) 89 | 90 | 减少视图层级 91 | 减少视图层级可以有效的减少内存消耗,因为视图是一个树形结构,每次刷新和渲染都会遍历一次。 92 | 93 | ### ViewStub标签 94 | 95 | 此标签可以使UI在特殊情况下,直观效果类似于设置View的不可见性,但是其更大的意义在于被这个标签所包裹的Views在默认状态下不会占用任何内存空间。 96 | 97 | ```xml 98 | 103 | 104 | ``` 105 | 106 | ### include标签 107 | 108 | 可以通过这个标签直接加载外部的xml到当前结构中,是复用UI资源的常用标签。 109 | 110 | ```xml 111 | 113 | ``` 114 | 115 | ### merge标签 116 | 117 | 它在优化UI结构时起到很重要的作用。目的是通过删减多余或者额外的层级,从而优化整个Android Layout的结构。 118 | 119 | ```xml 120 | 121 | 123 | 124 | 128 | 129 | 137 | 138 | 139 | ``` 140 | 141 | ```xml 142 | 146 | 147 | 151 | 152 | 159 | 160 | 161 | ``` 162 | 163 | ![img](http://upload-images.jianshu.io/upload_images/4037105-e93176a6e09be825.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 164 | 165 | 实现一模一样的效果,我们通过SDK自带工具检测android层级关系 166 | 167 | - 使用merge标签,布局少一个层级 168 | 169 | ![img](http://upload-images.jianshu.io/upload_images/4037105-397ffb39b2ab0bef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 170 | 171 | - 不使用merge标签,布局多一个层级 172 | 173 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ca547716b1b0d7df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 174 | 175 | Fragment优化 176 | 直接使用系统APP包下面的Fragment,不要使用V4包里面的Fragment可以减少层级结构。 177 | 178 | ## 使用ThreadPool优化代码(线程池实现原理) 179 | 180 | ### 1. new Thread的弊端 181 | 182 | 执行一个异步任务你还只是如下new Thread吗? 183 | 184 | new Thread的弊端如下: 185 | 186 | - 每次new Thread新建对象性能差。 187 | - 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。 188 | - 缺乏更多功能,如定时执行、定期执行、线程中断。 189 | 190 | 相比new Thread,Java提供的四种线程池的好处在于: 191 | 192 | - 重用存在的线程,减少对象创建、消亡的开销,性能佳。 193 | - 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。 194 | - 提供定时执行、定期执行、单线程、并发数控制等功能。 195 | 196 | ### 2. Java 线程池 197 | 198 | Java通过Executors提供四种线程池,分别为: 199 | newCachedThreadPool() 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 200 | newFixedThreadPool() 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 201 | newScheduledThreadPool() 创建一个定长线程池,支持定时及周期性任务执行。 202 | newSingleThreadExecutor() 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 203 | 204 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 205 | 206 | 微信公众号名称:Android干货程序员 207 | 208 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /性能优化/内存泄漏监测.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [Monitors使用配套视频](https://v.qq.com/x/page/x0393gf7qp6.html) 48 | - [DDMS-Heap配套视频](https://v.qq.com/x/page/e03933o0tp7.html) 49 | - [leakcanary配套视频](https://v.qq.com/x/page/o0382aiamwt.html) 50 | 51 | ## 12-如何对android应用进行内存性能分析 52 | 53 | #### 如何查看项目中内存泄漏? 54 | 55 | ![img](http://upload-images.jianshu.io/upload_images/4037105-4a0d70f4ff3c47fa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 56 | 57 | > AS的Memory窗口如下,详细的说明这里就不解释了,很简单很直观(使用频率高): 58 | 59 | ![img](http://upload-images.jianshu.io/upload_images/4037105-303debd142d5a3d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 60 | 61 | > DDMS-Heap内存监测工具窗口如下,详细的说明这里就不解释了,很简单(使用频率不高): 62 | 63 | ![img](http://upload-images.jianshu.io/upload_images/4037105-340416c85d9db68b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 64 | 65 | dumpsys meminfo命令如下(使用频率非常高,非常高效,注意:adb shell dumpsys meminfo不跟参数直接展示系统所有内存状态): 66 | 67 | ![img](http://upload-images.jianshu.io/upload_images/4037105-bd446bdbe1c0d05b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 68 | 69 | Android应用内存泄露leakcanary工具定位分析 70 | 71 | leakcanary是一个开源项目,一个内存泄露自动检测工具,是著名的GitHub开源组织Square贡献的,它的主要优势就在于自动化过早的发觉内存泄露。 72 | 73 | ![img](http://upload-images.jianshu.io/upload_images/4037105-92ea80d780f88d1a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 74 | 75 | 关于leakcanary工具的配置使用方式这里不再详细介绍,可以参考官方说明使用: 76 | [https://github.com/square/leakcanary](https://github.com/square/leakcanary) 77 | 78 | > Android应用内存泄露MAT工具定位分析 79 | 80 | Eclipse Memory Analysis Tools是一个专门分析Java堆数据内存引用的工具,我们可以使用它方便的定位内存泄露原因,核心任务就是找到GC ROOT位置即可 81 | 82 | ![img](http://upload-images.jianshu.io/upload_images/4037105-09c1fc109df0e02d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 83 | 84 | 写篇文章和录制视频从选题,思考,组织,写作,编辑至少需要一个多小时,而您点赞和转发只需要0.1秒,就可以带给我更大的动力,何乐而不为呢? 85 | 86 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 87 | 88 | 微信公众号名称:Android干货程序员 89 | 90 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /源码分析/README.md: -------------------------------------------------------------------------------- 1 | ## 源码分析相关面试题 2 | 3 | - [Volley源码剖析](Volley源码剖析.md) 4 | - [注解框架内部实现原理](注解框架内部实现原理.md) 5 | - [okhttp内核剖析](okhttp内核剖析.md) 6 | - [Android源码编译实现静默安装和静默偷拍](Android源码编译实现静默安装和静默偷拍.md) -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-1.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-10.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-11.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-12.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-13.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-14.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-15.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-16.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-17.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-18.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-19.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-2.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-20.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-21.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-22.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-3.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-4.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-5.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-6.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-7.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-8.png -------------------------------------------------------------------------------- /源码分析/img/静默安装和静默偷拍-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackChan1999/Android-Interview/a9519d7d9ba11d23b3ecc7b90e09f31a903a58e3/源码分析/img/静默安装和静默偷拍-9.png -------------------------------------------------------------------------------- /登陆注册/Oauth的实现原理.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [配套视频](https://v.qq.com/x/page/p03953hoam3.html) 48 | 49 | ## 腾讯QQ第三方登录的实现原理? 50 | 51 | > Oauth当中的角色: 52 | 53 | 1. Service Provider(服务提供方) 54 | 55 | 服务提供方通常是网站,在这些网站当中存储着一些受限制的资源,如照片、视频、联系人列表等。这些网站通常使用用户名和密码来确认用户的身份。比如新浪微博的开放平台就是Service Provider。 56 | 57 | 2. User(用户) 58 | 59 | 存放在服务提供方的受保护的资源的所有者。用户持有可以登录服务提供者网站的用户名和密码。用户不希望把自己的资源公开,但是用户却需要将这些资源共享给其他网站或应用程序(如用户希望使用第三方开发的新浪微博客户端来访问自己的资源,但又不希望第三方应用知道自己的用户名和密码)。 60 | 61 | 3. 客户端(Client) 62 | 63 | 要访问服务提供方资源的第三方应用,可以是web应用程序、桌面应用程序或者是手机应用程序。客户端需要得到授权之后才能访问相应的资源。 64 | 65 | > Oauth的认证和授权过程: 66 | 67 | 1. 用户使用第三方的客户端(如访问第三方的网站,或使用第三方的应用),想对存放在服务提供者的某些资源进行操作 68 | 2. 第三方网站或应用向服务提供方请求一个临时令牌(Request Token) 69 | 3. 服务提供方验证第三方的身份后,授予其一个临时令牌 70 | 4. 第三方获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供者 71 | 5. 用户在服务提供者的授权页面上输入自己的用户名和密码,然后授权该客户端访问相应的资源 72 | 6. 授权成功后,服务提供方引导用户返回第三方网站的的网页 73 | 7. 客户端根据临时令牌从服务提供方那里获取访问令牌(Access Token) 74 | 8. 服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌 75 | 9. 客户端使用获取的访问令牌访问存放在服务提供方上的相应的资源 76 | 77 | Oauth简单示意图 78 | 79 | ![img](http://upload-images.jianshu.io/upload_images/4037105-b1e90838ef009145.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 80 | 81 | Oauth全面的示意图 82 | 83 | ![img](http://upload-images.jianshu.io/upload_images/4037105-7931074dfb4fa188.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 84 | 85 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 86 | 87 | 微信公众号名称:Android干货程序员 88 | 89 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /登陆注册/README.md: -------------------------------------------------------------------------------- 1 | ## 与登录相关面试题 2 | 3 | - [Oauth的实现原理](Oauth的实现原理.md) 4 | - [Token的实际意义](token的实际意义.md) 5 | - [微信扫码登录内部实现原理](微信扫码登录内部实现原理.md) -------------------------------------------------------------------------------- /登陆注册/Token的实际意义.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | 今天文章比较简单,主要是为了录制面试题系列,保证文章的完整性来帮助那些想找工作的哥们,各位高级程序员请勿拍砖,不过把下面三段视频都看完,多多少少会有些收获。。。 46 | 47 | ### 本文配套视频: 48 | 49 | - [为什么需要token配套视频](https://v.qq.com/x/page/c0395s3jd4f.html) 50 | - [一分钟登录配套视频](https://v.qq.com/x/page/p0395khlfdz.html) 51 | - [一分钟解析登录配套视频](https://v.qq.com/x/page/r03959jvnjm.html) 52 | 53 | ## 在android开发中,用户登录时,客户端会接收到token值,请描述一下对token的理解? 54 | 55 | ### Token的引入: 56 | 57 | Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。 58 | 59 | ### Token的定义: 60 | 61 | Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 62 | 63 | 使用Token的目的: 64 | Token的目的是为了验证用户登录情况以及减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。 65 | 66 | ### Token的应用: 67 | 68 | 1. 当用户首次登录成功之后, 服务器端就会生成一个 token 值,这个值,会在服务器保存token值(保存在数据库中),再将这个token值返回给客户端 69 | 2. 客户端拿到 token 值之后,使用sp进行保存 70 | 3. 以后客户端再次发送网络请求(一般不是登录请求)的时候,就会将这个 token 值附带到参数中发送给服务器 71 | 4. 服务器接收到客户端的请求之后,会取出token值与保存在本地(数据库)中的token值做对比 72 | 5. 如果两个 token 值相同, 说明用户登录成功过!当前用户处于登录状态 73 | 6. 如果没有这个 token 值, 没有登录成功 74 | 7. 如果 token 值不同: 说明原来的登录信息已经失效,让用户重新登录 75 | 76 | ### 使用一分钟利用开源中国接口获取登录token 77 | 78 | ### 利用一分钟时间解析服务器返回的token数据 79 | 80 | 懒得写文字了,直接看视频吧,看完会有不小的收获哦 81 | 82 | ## 登录和注销 (Cookie, Session) 83 | 84 | 85 | * 登陆过程 86 | 1. 先把用户名和密码传给服务器(请求头中没有Cookie) 87 | 2. 服务器验证用户名和密码 88 | 3. 验证通过->响应头中返回(Cookies)一个或多个key=value;key1=value1 89 | 4. 客户端保存这些Cookies到本地文件. 90 | 91 | * 请求数据过程 92 | 1. 如果没有Cookie, 只能获取到公共信息. 93 | 2. 把Cookie放到请求头中, 可以获取到Cookie对应的账号的隐私数据. 94 | 3. 如果Cookie超时了(一小时, 一周, 一个月), 服务器同样不返回隐私数据. 95 | 96 | * 注销过程 97 | 1. 删除本地的Cookie 98 | 2. 以后的请求头中都没有Cookie 99 | 3. 服务器不会再知道客户端是谁, 会话结束. 100 | 101 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 102 | 103 | 微信公众号名称:Android干货程序员 104 | 105 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /登陆注册/微信扫码登录内部实现原理.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [配套视频](https://v.qq.com/x/page/u03952rbbkc.html) 48 | 49 | ## 26微信扫码登录内部实现原理? 50 | 51 | ### 打开网页版微信,可以看到如下的页面: 52 | 53 | ![img](http://upload-images.jianshu.io/upload_images/4037105-c80fa67b87efba8b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 54 | 55 | 如果你用我查查、支付宝、新浪微博等软件扫码二维码,你会发现此二维码解析出来是如下的网址: 56 | 57 | ``` 58 | https://login.weixin.qq.com/l/obsbQ-Dzag== 59 | ``` 60 | 61 | 接下来详细介绍一下扫码登录具体的每个步骤: 62 | 63 | ![img](http://upload-images.jianshu.io/upload_images/4037105-05483767b3c483c7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 64 | 65 | ① :用户 A 访问微信网页版,微信服务器为这个会话生成一个全局唯一的 UUID二维码,上面的 URL 中 obsbQ-Dzag== 就是这个 UUID,且每次刷新后都会改变。这样可以保证一个UUID只可以绑定一个账号和密码,确定登录用户的唯一性。我刷新三次,扫描结果如下,其中最后面那串数字就是UUID:此时系统并不知道访问者是谁。 66 | 67 | ![img](http://upload-images.jianshu.io/upload_images/4037105-91bc93e6ba3c5418.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 68 | 69 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ad2ce3ee1eee2a4b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 70 | 71 | ② :除了返回唯一的uid,实际上打开这个页面的时候,浏览器跟服务器还创建了一个长连接,请求uid的扫描记录。如果没有,在特定时长后会接到状态码408(请求超时),表示应该继续下一次请求;如果接到状态码201(服务器创建新资源成功),表示客户端扫描了该二维码。 72 | 73 | 请求超时:返回408 74 | 75 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ec68032ffe40ad0f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 76 | 77 | 扫码成功:返回201 78 | 79 | ![img](http://upload-images.jianshu.io/upload_images/4037105-ce5fbb042498a8ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 80 | 81 | ③:手机上的微信是登录状态,用户点击确认登录后,手机上的微信客户端将微信账号和这个扫描得到的 ID 一起提交到服务器 82 | 83 | ![img](http://upload-images.jianshu.io/upload_images/4037105-71c47fa7f96bbcfc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 84 | 85 | ④ :服务器将这个 ID 和用户 A 的微信号绑定在一起,并通知网页版微信,这个 ID 对应的微信号为用户 A,网页版微信加载用户 A 的微信信息,至此,扫码登录全部流程完成 86 | 87 | 总的来说,微信扫码登录核心过程应该是这样的:浏览器获得一个唯一的、临时的UUID,通过长连接等待客户端扫描带有此UUID的二维码后,从长连接中获得客户端上报给服务器的帐号信息进行展示。并在客户端点击确认后,获得服务器授信的令牌,进行随后的信息交互过程。 在超时、网络断开、其他设备上登录后,此前获得的令牌或丢失、或失效,对授权过程形成有效的安全防护,类似的应用还有扫码支付、扫码加公众号等功能. 88 | 89 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 90 | - 微信公众号名称:Android干货程序员 91 | 92 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /经验分享/2016年4月某公司面试题及面试流程.md: -------------------------------------------------------------------------------- 1 | ## 2016年4月某公司面试题及面试流程 2 | 3 | ### **1. 静态内部类、内部类、匿名内部类,为什么内部类会持有外部类的引用?持有的引用是this?还是其它?** 4 | 5 | - 静态内部类:使用static修饰的内部类 6 | - 内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类 7 | - 匿名内部类:使用new生成的内部类 8 | - 因为内部类的产生依赖于外部类,持有的引用是类名.this 9 | 10 | 11 | ### **2. ArrayList和Vector的主要区别是什么?** 12 | ArrayList在Java1.2引入,用于替换Vector 13 | Vector:线程同步,当Vector中的元素超过它的初始大小时,Vector会将它的容量翻倍 14 | ArrayList:线程不同步,但性能很好,当ArrayList中的元素超过它的初始大小时,ArrayList只增加50%的大小 15 | [java集合类框架](http://yuweiguocn.github.io/java-collection/) 16 | 17 | http://blog.csdn.net/axi295309066/article/details/54089986 18 | 19 | ### **3. Java中try catch finally的执行顺序** 20 | 先执行try中代码发生异常执行catch中代码,最后一定会执行finally中代码 21 | 22 | ### **4. switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?** 23 | switch支持使用byte类型,不支持long类型,String支持在java1.7引入 24 | 25 | ### **5. Activity和Fragment生命周期有哪些?** 26 | - Activity 27 | 28 | onCreate→onStart→onResume→onPause→onStop→onDestroy 29 | 30 | - Fragment 31 | 32 | onAttach→onCreate→onCreateView→onActivityCreated→onStart→onResume→onPause→onStop→onDestroyView→onDestroy→onDetach 33 | 34 | ### **6. onInterceptTouchEvent()和onTouchEvent()的区别?** 35 | onInterceptTouchEvent()用于拦截触摸事件 36 | onTouchEvent()用于处理触摸事件 37 | 38 | ### **7. RemoteView在哪些功能中使用** 39 | APPwidget和Notification中 40 | 41 | ### **8. SurfaceView和View的区别是什么?** 42 | SurfaceView中采用了双缓存技术,在单独的线程中更新界面 43 | View在UI线程中更新界面 44 | 45 | ### **9. 讲一下android中进程的优先级?** 46 | 47 | - 前台进程 48 | - 可见进程 49 | - 服务进程 50 | - 后台进程 51 | - 空进程 52 | 53 | ### 10. 代码查错题,没记下来 54 | tips:静态变量持有Activity引用会导致内存泄露 55 | 56 | ### 11. 一面 57 | service生命周期,可以执行耗时操作吗? 58 | JNI开发流程 59 | Java线程池,线程同步 60 | 自己设计一个图片加载框架 61 | 自定义View相关方法 62 | http ResponseCode 63 | 插件化,动态加载 64 | 性能优化,MAT 65 | AsyncTask原理 66 | 65k限制 67 | Serializable和Parcelable 68 | 文件和数据库哪个效率高 69 | 断点续传 70 | WebView和JS 71 | Android基础——Service 72 | Android基础——IntentService 73 | Android开发指导——Service 74 | Android开发指导——绑定Service 75 | Android开发指导——进程间通信AIDL 76 | Android面试基础知识总结(一) 77 | Android面试——APP性能优化 78 | [Android中Java和JavaScript交互](http://droidyue.com/blog/2014/09/20/interaction-between-java-and-javascript-in-android/) 79 | [WebView 远程代码执行漏洞浅析](http://jaq.alibaba.com/blog.htm?spm=0.0.0.0.oMsDAl&id=48) 80 | [WebView中的Java与JavaScript提供【安全可靠】的多样互通方案](https://github.com/pedant/safe-java-js-webview-bridge) 81 | 82 | ### 12. 二面 83 | 所使用的开源框架的实现原理,源码 84 | 没看过,被pass了 85 | 去面试之前把用到的开源框架源码分析一定要看看啊 86 | [codekk:开源框架源码解析](http://codekk.com/open-source-project-analysis) 87 | [2016Android某公司面试题](http://yuweiguocn.github.io/interview-2016-big-company/) -------------------------------------------------------------------------------- /经验分享/2017届实习生招聘面经.md: -------------------------------------------------------------------------------- 1 | [2017届实习生招聘面经(今日头条,腾讯,阿里,360)](http://www.jianshu.com/p/12654b063553) 2 | 3 | # 1. 阿里内推 4 | 5 | 在三月的某一天,当我还沉浸在代码世界的时候,突然一声铃声响,拿起手机一看,杭州电话==大三春招第一次面试开始了。 6 | 7 | ## 阿里一面 8 | 9 | 问的问题不多,也就26分钟的样子 10 | 11 | 你用过哪些集合类?==太多了,随便说了些 12 | 那你说说ArrayList,LinkedList的区别(还是挺简单的,一般用过的都说会)。 13 | 说说hashMap是怎样实现的(这个之前看过,顺利回答上。还回答了多线程的问题出现的原因,面试官表示很惊讶的样子) 14 | 说说可重入锁 15 | 16 | 说说view绘制过程和事件分发机制,我大概回答了下。然后面试官又问:onTouch和onTouchEvent是什么区别?如果我重写了ontouch和onClick,它们的调用顺序是怎样的?什么时候会不调用onClick? 17 | 18 | handler的是怎样实现的? 19 | 20 | 由于项目里面用到了picasso,所以最后问了下picasso实现原理。 21 | 一面结束,最后面试官居然问我是不是第一次面试== 估计是帮紧张了。不过一面过程中面试官心情还不错,都是笑着问的。 22 | 23 | 当天晚上接到二面,面试官太累了,约我第二天面试。 24 | 25 | ## 阿里二面 26 | 27 | 二面气氛一直不对,感觉面试官非常严肃,一来就感觉很有压力 28 | 29 | ## 自我介绍 30 | 操作系统里面线程和进程的区别(挺基础的) ,接着麻烦就来了;我说完大致区别后,他就问,你说进程里面线程是共享内存的,那么一个进程最大能占多少内存?(懵逼,这是什么意思?考的分页知识?)。然后这里我想了一下,说应该和硬件有关,他继续问,有什么关系?(应该和地址总线有关,当时没想起,他叫我再想想,要是你设计的系统,应该和什么有关,还是没答上)。 31 | 32 | 你项目中图片是怎么处理的?回答:picasso,顺便说了下picasso原理。然后又问:那么picasso里面有多少个线程来加载图片?要是网络不同,线程数目分别是多少? 33 | 34 | 布局优化(这里开始说错了一点,然后面试官很生气的样子,自我感觉就要挂了) 35 | 项目中有哪些优化? 36 | 37 | 最后果然挂了(惨痛的经历,不过为后面打下了很好的基础,至少不 怎么紧张了) 38 | 39 | 然后后面就没有面试了 40 | 41 | 直到4月腾讯面试 42 | 43 | # 2. 腾讯面经 44 | 45 | 腾讯是走的正常渠道,到成都现场面试 46 | 47 | ## 一面 48 | 49 | 面试场地是在一个宾馆里面,一对一面试,face to face还是有点紧张的 50 | 51 | ## 自我介绍 52 | java多态你了解多少? 53 | 54 | 你说说重写和重载区别,然后拿了纸笔,手写一个能体现多态的例子 55 | 56 | 说说java在运行main函数之前做了哪些工作? 57 | 58 | 这个我居然从启动虚拟机→加载类→初始化类一直说到执行Main 59 | 60 | 你对大尾小尾了解多少? 61 | 62 | 我反问:您说的是大小端么? 他说对,然后我正准备给他解释的时候,他又拿了一张纸:用java写一个判断大小尾的程序 63 | 64 | java静态方法能不能被重写? 答:不能。 问:为什么? 65 | 为什么java静态方法不能调用普通方法?普通方法能调用静态方法?(其实还是实例引用问题) 66 | java内存模型和GC机制 67 | 68 | 其实腾讯面试官感觉都很nice,他称呼我 都用您。感觉怪怪的,而且礼仪非常好。最后面完后,我问我面试得怎样?他说你了解的知识还是挺宽的,然后问了我一句要不要去做游戏?当然要啊! 69 | 70 | 然后就走了。然后就没有然后了,晚上查状态是不适合。 71 | 72 | ## 霸面一面 73 | 74 | 腾讯面试后,感觉不怎么死心,又跑去长沙霸面了,我一去,HR说移动端基本已经招满了,你可以把简历放在这儿,要是有面试机会的话,我会通知你。然后我心情失落地回去了。 75 | 76 | 当我刚到住处,刚出电梯,HR就来电话了,叫我去面试 77 | 78 | 我那个开心啊,把平时20分钟的路程当成10分钟不对跑过去,直接一面。 79 | 80 | 一面面试官也很nice,还惊讶我从重庆来 81 | 82 | Hashmap原理 83 | hashcode和equals还有==的关系 84 | 用hashmap实现hashset。。我之前看过的,忘记了。然后按照我的想法回答了。(最后面试官告诉了我该怎样实现==) 85 | 内部类访问外部类的变量有什么问题? 86 | 87 | android里面onStop和onPause本质区别。什么时候可以存数据? 88 | 两个单链表寻找有没有交点,然后再寻找交点位置 89 | android oom怎么解决 90 | 还问了一些项目的问题 91 | 其实中间还问了几个算法,忘记是什么了,后面想到了的话会加上的。 92 | 93 | ## 二面 94 | 95 | 二面面试官感觉很牛的样子,一直技术轰炸 96 | 97 | 告诉我你所直到的所有关于java虚拟机的东西,我说了好久好久。还说了新生代大概什么时候会加入老年代 98 | binder机制 99 | handler原理, Message,loop,messageQueue关系,handler内存泄露问题。 100 | TCP三次握手,用纸画出来 101 | 为什么TCP是可靠的,UDP早不可靠的?为什么UDP比TCP快? 102 | 面试官看到了我的项目,然后问了我一个用到的框架的原理,还问了我里面的很多细节,估计是以为我直接看的别人的博客了解到的这些知识,还好我是自己看了源码 103 | 算法:几百万个QQ号 ,找出前100个消费最高的QQ号。直接小顶堆什么的 104 | android四大组件 ,这里扩展了很多,毕竟非常熟悉,还说了很多坑,很多实现原理(比如activity start原理) 105 | 还问了优缺点 106 | (也有一些问题忘记了) 107 | 这次面试很久,忘记带水了,出来我直接喝完了一瓶怡宝 108 | 这交自我感觉答得不错,然后过了2个小时就收到HR面通知 109 | 110 | ## HR面 111 | 112 | 自我介绍 113 | 项目里面怎么解决安全问题的?好可怕,会技术的HR 114 | 有没有女朋友? 115 | 家在哪里 116 | 有没有亲戚在腾讯? 117 | 我问了下要是过了的话大概会在哪里实习?HR说在深圳,还问我有什么问题么?我说没有,我爸妈也在那边,然后他在我简历上面记了一下。 118 | 为什么要学习android? 119 | HR面就10多分钟,很快,和我一起面试的还有几个学生,也都是10来分钟,然后HR叫我等结果 120 | 121 | 然后等啊等,等到现在还没有结果 122 | 123 | # 3. 360面试 124 | 125 | 360全程视频面试加写代码什么的 126 | 127 | ## 一面 128 | 129 | 写一个adapter,我后面忘记了getView的一个参数,一直在那里想,面试官问我是不是在编译器里面写,我说我在想怎么写。 130 | hashmap原理 131 | java可重入锁 132 | 排序算法和稳定性,快排什么时候情况最坏? 133 | 一个获全国奖的项目问了我20分钟,特别是service不被杀死的方法,我说了4种才放过我,还问了我具体实现,特别是在JNI里面实现的时候 134 | 项目中界面适配,自定义过view没有? 135 | NFC读卡,这个是我的项目,我说了具体实现,然后就放过我了 136 | 我项目中用了google map 和定位,他问怎么定位的?居然问了我具体API,我还说了里面的坑,国产手机阉割了一部分的问题 137 | 一面大概1个半小时,头昏脑涨,然后面试官并不放过我,叫我等等。他去叫二面面试官 138 | 139 | ## 二面 140 | 141 | http协议了解多少,说说里面的协议头部有哪些字段? 142 | https了解多少?为什么百度全部都用了https包括首页 143 | 散列表的基础知识,里面也问了hashmap(可见hashmap重要性) 144 | 项目问题,几个项目都问了,什么分工啊什么的 145 | 问了我很多项目中开发的问题,还好基本都答出来了,二面基础知识基本没多少,都是项目问题 146 | 二面接近一个半小时,还好在寝室面试,边面边喝水,二面脑袋都是糊的 147 | 148 | 二面完后,10分钟打电话通知一周内有HR面 149 | 150 | ## HR面 151 | 152 | HR面的时候,我正在火车上,HR说只有15分钟,我说当场面了,因为我那个时候正停在一个大站里面,要停半个小时 153 | 154 | 自我介绍,问了我所有项目的分工问题和设计等问题,好几个项目,这里就花了接近20分钟,然后火车开走了,然后大家都知道,悲催了,没信号 155 | 156 | 等到我有信号的时候,再给HR打电话约好第二天继续面。 157 | 第二天 158 | 159 | 继续项目分工 160 | 中兴实习情况?为什么最后没留下?(要读书啊) 161 | 开发的一些规范 162 | 投了XX公司和XX公司没有?为什么没投XX公司?哎,这里太年轻别坑了 163 | 怎么看待3Q大战(大姐,这个我怎么来说呢?) 164 | 问了我实习时间,希望实习的地点,希望做哪方面? 165 | 你觉得你一面和二面哪一面成绩更好?每一面大概多少分 166 | 优缺点 167 | 每个问题都问了很久,因为每个过后都接着往下问了的。整个HR面都1小时13分钟,累啊!!说好的15分钟呢 168 | 169 | 然后N天后,收到360拒信。 170 | 171 | # **4. 今日头条** 172 | 173 | 今日头条也是我唯一过的公司,一面还好,二面全程技术轰炸,HR面聊得挺好,虽然有点短 174 | 175 | 今日头条我是内推的,N天后给我发邮件和电话约面试,本来是北京面试的,结果去不了,就电话面试了。 176 | 177 | 两次技术面试也是接近2个小时 。一面面试官面完后,叫我去吃饭,过会儿继续面,天真的我以为已经二面了,然而并不是,这个时候面试官还是建议去北京面试,过的机会大些,这个时候哪还有心情吃饭,一直等面试官的电话,结果继续面的时候直接写了一个代码就OK了,代码是在一个矩阵是查找有没有某个数,矩阵从左到右依次增大(忘记是增大还是减小了),从上到下也一样。由于电脑问题,我还是翻墙去写代码的,写代码的时候,由于网不稳定,还经常断 178 | 179 | 写完直接叫我等二面,过了会儿二面面试官马上来了电话 180 | 181 | 二面面试官感觉很随和,从Java的用法问到了虚拟机,问到了操作系统,最后深入问到了一个编译原理。还问了一些C语言的东西。 182 | 还问了排序。 183 | 然后可能是因为我所有东西是自学的,面试官在问之前都问了我了解不,不了解就重新换一个。还问了一些图论最短路径问题(还好面试前不久做了一个比赛,华为的未来寻路,就是最短路径问题),这个答得还行,说了一些经典算法,还有一些只能算法,还有一些改进等。 184 | 185 | 然后就是我项目中的问题,因为我用了rxjava,picasso,retrofit等开源项目,所以面试官问了我retrofit是如何处理注解的,我直接讲了源码,其过我博客里面也写过了这个,然后面试官可能发现我了解,就直接跳过了这个。然后问了我rxjava的东西,我结合博客看了部分源码,还问了rxjava里面用了大量的这些,是什么意思。 186 | 187 | 过后问我了解github上的一些开源项目不,我说了解一些,然后就是butterknife了,然后我回答错了,以为是注解+反射。后面挂电话后,找了时间分析了源码,还真不是反射==[butterknife分析在这里。](http://www.jianshu.com/p/0f3f4f7ca505) 188 | 189 | 今日头条感觉是我面试问题水平最高的,不再局限于基础知识,问了很多很深入的东西。感觉面试官都是根据我具体情况问的,随手丢出问题,直到我回答不上。总以为二面会挂。 190 | 191 | 结果在某天中午接到了HR的电话,由于那个时候有事,重新约了时间== 192 | 当时都有HR面恐惧症了,因为前面两次HR面后都没消息了== 193 | 194 | ## **HR面** 195 | 196 | 时间很短,几个问题而已,回答完就叫我等结果,说5月中旬会出结果。 -------------------------------------------------------------------------------- /经验分享/Android 曲折的求职之路.md: -------------------------------------------------------------------------------- 1 | ## 个人近况 2 | 3 | [本人博客](http://mikeejy.github.io/) ,先说下博主最近近况,今年 2 月份从信和财富出来,去了一家创业公司结果不堪 996 的压榨,5 月底毅然离职没想到目前市场这么萧条,怪自己太作,有好的机会不好好把握,非得出来受虐哈,人都是犯贱的……所以目前整理几家去过的公司以免以后被坑。 4 | 5 | ## 金开门(好贷网旗下孵化创业公司) 6 | 7 | 这公司是在 BOSS 直聘上投的 8 | 9 | 总体面试还算不错吧 Android 技术那面一般也不会问特别深主要是最新的主流技术一般会问下,还有就是之前的项目会大致问一下 10 | 11 | 接下来是总监面,总监是个蛮不错的人,满有亲和力的,大概就是聊推送这一块的,还有支付,因为这公司主要业务是聚合支付相关的,总体还 OK 12 | 13 | 接着是 HR 谈薪水还有介绍公司近况,貌似最近一直是 995 的节奏 14 | 15 | 最后是大 Boss 面貌似很屌的说了一句目前我们就是 996 的节奏(应该是试探我的),我觉得跟他也没啥好谈,他一幅咄咄逼人的气势,总体感觉 BOSS 应该是个坑比,这个人的感觉貌似跟博主之前在16年遇到的创业公司的老板一个鸟样,所以就没有后续了... 16 | 17 | ## 音悦台 18 | 19 | 这个也是在 Boss 直聘上约的,公司就在三里屯 SOHO 20 | 公司主要业务主打 MV 的剩下的我就不多说了,前几年业务还是挺火的 21 | 22 | HR 人还是很不错的,公司的环境神马的都没得说,妹子也多,没给offer确实感觉挺遗憾的 23 | 24 | 首先光技术面问的就蛮深入的,基本最近貌似招人都比较苛刻~多线程,线程池,handler,Looper 源码层,activity 源码,四种启动模式,生命周期,View 的绘制流程,自定义 view,手势传递问的最复杂也最多 25 | 还有一些开源项目相关的问题吧 okhttp,glide,eventbus 相关的 26 | 27 | ## 1905 电影网 28 | 29 | 这个是在拉勾上投的,公司在西直门 30 | 我敢说这个面试官是这么多年我遇到的最能装逼一个,当然人家技术也蛮不错的,你不会的,遇到问题的,人家也耐心给你讲解哟,无形装逼,最为致命啊!如果你技术不是很好的话千万不要去这家公司找虐 31 | 32 | 博主之前有个朋友也来过这家面试,貌似最后给说开不了他的工资,还跟他说来面试很多 33 | 给我种感觉 就是面试造核弹,工作拧螺丝?最后还问了我项目里有啥亮点 34 | 问题蛮多的好多都忘了,大致记住几个 35 | 36 | Glide ,Picasso 都分别有几个线程池 37 | 38 | Asynctask 源码,为什么 android4.0 以后是串行 39 | 40 | OnMeasure 方法几个参数对应含义(这个题问的最多的所以我把答案贴上O(∩_∩)O~ 41 | 42 | 首先我们要理解的是 widthMeasureSpec, heightMeasureSpec 这两个参数是从哪里来的?onMeasure() 函数由包含这个 View 的具体的 ViewGroup 调用,因此值也是从这个ViewGroup 中传入的。这里我直接给出答案:子类 View 的这两个参数,由 ViewGroup 中的 layout_width,layout_height 和 padding 以及 View 自身的 layout_margin 共同决定。权值 weight 也是尤其需要考虑的因素,有它的存在情况可能会稍微复杂点。 43 | 44 | 了解了这两个参数的来源,还要知道这两个值的作用。我们只取 heightMeasureSpec 作说明。这个值由高 32 位和低 16 位组成,高 32 位保存的值叫 specMode,可以通过如代码中所示的 MeasureSpec.getMode() 获取;低 16 位为 specSize,同样可以由MeasureSpec.getSize() 获取。那么 specMode 和 specSize 的作用有是什么呢?要想知道这一点,我们需要知道代码中的最后一行,所有的 View 的 onMeasure() 的最后一行都会调用 setMeasureDimension() 函数的作用——这个函数调用中传进去的值是 View 最终的视图大小。也就是说 onMeasure() 中之前所作的所有工作都是为了最后这一句话服务的。 45 | 46 | 我们知道在 ViewGroup 中,给 View 分配的空间大小并不是确定的,有可能随着具体的变化而变化,而这个变化的条件就是传到 specMode 中决定的,specMode 一共有三种可能: 47 | 48 | MeasureSpec.EXACTLY:父视图希望子视图的大小应该是 specSize 中指定的。 49 | 50 | MeasureSpec.AT_MOST:子视图的大小最多是 specSize 中指定的值,也就是说不建议子视图的大小超过 specSize 中给定的值。 51 | 52 | MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小。) 53 | 54 | - 广播怎么不跨进程 55 | - Rxjava 操作符 56 | - Rxjava 1 2的区别 57 | - 还有问了轮播怎么让用户按下三秒之后继续翻页 58 | - 还有五种进程级别 59 | - 多线程下载,3个线程如何下载10M的文件 60 | - 两列 Recyclerview 如果是表格布局怎么添加 header view 61 | - Thread 和 intent service 62 | 63 | 最牛B的一个问题是类似天猫这种大厂APP实现的全局应用代理是怎么实现的 64 | (本意就是类似于推送的时候处理推送的逻辑不写一大堆switch case,而是在入口处动态去配置就可以) 65 | 66 | ## 凡普金科(普惠金融旗下) 67 | 68 | 这个是在拉勾上投的,公司在银河 SOHO 69 | 70 | 当时面试地点其实是发的有问题的,前台大门明明在A座嘛,你非得发个 D 座那边的位置,结果那边的门锁了,我敲了半天才有人开,我才知道走错门了应该从 A 座的电梯上来,可是就是发的 D 座,这里吐槽下。。。然后前台妹子给我的笔试题居然是 Java 的(貌似给错了) 71 | 72 | 面试的深度基本跟 1905 那哥们差不多,也是 activity 启动模式跟手势传递还有 Looper 的源码那块问的比较多只是这个人最后问了一个尺子的效果:附上[项目地址]( https://github.com/kailaisi/WheelSelect)哈,类似这个地址 demo 的实现效果只是年龄换成了金额(毕竟是做金融的公司 当然这样咯) 73 | 74 | 只说还有复试,但是也是没下文了 75 | 76 | ## 映社(木蚂蚁) 77 | 78 | 这个公司绝对是坑比中的战斗机,去了就让你一直等啊等,等到花都谢了的那种 79 | PS:他们现在的项目主要是做直播的产品叫“映社”(有种抄袭映客的嫌疑~~) 80 | 去的时候公司前台都没人,打电话也没人接,后来一个快递小哥进门了我和另外的一个也是面试的才进去 81 | 82 | 首先是有笔试题的话说蛮弱智的(做完感觉也不会怎么看,完全就是浪费时间啊啊)然后那哥们把你领到一个类似小会议室的屋子里,这哥们给人的感觉技术也很一般,没有之前面的那么强势,基本都是照着简历问的,问直播跟FFmpeg那块偏多,贝塞尔曲线?自定义 View,偶尔穿插下 retrofit,Rxjava,热修复神马的,面完之后就出去了让你一直等啊等,等了快 40 分钟的时候进来说总监在开会 83 | 84 | 这个公司真特么的是个奇葩,你约人的时候不会挑个没会的时间么,貌似拉勾上有个面php 的哥们跟我一样也是被搁置一直等啊等,真是日了狗了!最后来了一句改天复试吧 85 | 86 | 只说还有复试,让我来我也不会来了 87 | 88 | ## Melons (北京知行远科技) 89 | 90 | 这家公司是我在拉勾上投的,公司成立于2016年太初创了(我能怎么办,我也很绝望啊,貌似最近拉勾的公司比较少,稀里糊涂就投了 91 | 92 | Boss 也是做 android 的,而且还是前最美应用的联合创始人,技术出身还是蛮不错的公司早 10 晚 8 做海外项目 93 | 94 | 但是目前的状况是跟别人挤在一间办公室里,那个隔壁组的貌似是 Google 天气的团队 95 | 96 | 技术面还是跟之前的那几家差不多,基本都不会看你做过的项目就咔咔的问底层源码咯,唯一不同的是启动模式那块多问了 taskAffinity 这个属性,我确实是没用过,面试官拿着 macbook 一个一个的循序渐进的问着,面试流程大概一个半小时左右,然后跟 boss 聊了聊薪资和之前为什么离职,因为是早上十点半约的,一直聊到了中午 12 点 40多 97 | 98 | 我中午饭都没吃,然后紧接着就去中关村准备下午那家的面试 99 | 100 | PS:今天还下着雨,挺苦逼的 101 | 102 | 目测不会发 offer,可能是小公司给不起薪资 103 | 104 | ## NewsDog (公司名字就叫这个薪资标的还挺高) 105 | 106 | 这家公司是我在拉勾上投的,公司应该是 B 轮了已经 107 | 因为是约的是下午两点,而且刚从 Melons 那里面完就来了,所以去这家公司的时候连中午饭都没吃,让前台给接了杯水暂时压压惊。。。 108 | 109 | 看简介公司应该是做海外市场主要是信息推荐跟数据挖掘的业务(不知道他们现在的产品是啥) 110 | 111 | 技术面主要是根据简历去问的,比较在意内存泄漏,内存优化还有 View 的过渡绘制这一块的东西,还有就是问了问图片开源库 Picasso v/s Imageloader v/s Fresco vs Glide 区别以及如何去选择吧,还有 eventbus 的源码以及注解的优点,其它的大概就是还问了问项目的难点之类的 112 | 113 | 比较操蛋的是没有讨论薪资,然后就直接送客了,不造差在哪里 114 | 115 | 这样的公司也是比较无语的,面试官给人的感觉是屌的一逼,有点高高在上了 116 | 117 | ## 曙光无限 118 | 119 | 曙光无限 这家公司是在 boss 上约的,公司地址在回龙观东大街的腾讯众创空间(办公楼的环境蛮好的),公司主打产品是海外的项目,旗下产品几十种还是蛮多的 120 | 121 | - 第一面 :只是人事先照着简历初略的聊了聊以前的项目经验,由于公司是做海外滤镜软件的,可能对图片算法这块要求蛮高的,福利这块目前是采取接近避税的方式,第一年还不给交住房公积金,貌似还需要第二面总监面,而且还要上机写demo... 122 | - 目前 android 行情 :从以往的面试分析来看基本 android 的行情接近饱和状态,薪资这块基本稍微要高点的话直接就给你 pass 然后可能用其它人候选人去对比,市场的行情还真是惨淡 123 | - 后续 :没有通知进一步的面试 124 | 125 | ## 遇见科技 126 | 127 | 遇见科技 这家公司是在 boss 上约的,公司地址在知春路附近,公司的办公环境也还不错哈,项目应该是一款社交软件,貌似起步还是蛮早的,已经做了几年了 128 | 129 | 第一面 :主要是技术面,问的以简历的内容为主还有面试官会看以往做过的项目(现在看项目的公司确实不多了)比较在意的是之前做过的项目整体的流程,整体架构设计模式还有业务这块的详情,基本都是围绕做的项目这块的技术点来的涉及的知识点也基本涵盖了目前比较流行的开源组件,还有会问一些关于同类框架之前的区别与对比:比如 volley 与 okhttp,图片框架,数据库 greenDao,realm,litepal 等等性能方面的问题 130 | 131 | 第二面 :第一面没什么问题之后会和 HR 进一步沟通,主要介绍了公司目前的产品方向还有项目节奏,福利待遇神马之类的 132 | 133 | 总监面 :能见到总监也基本很不容易了,基本也是聊了聊以往的项目,可能比较看重的是解决问题的能力,会问擅长哪方面(Ui 还是业务?)项目难点等等。。。 134 | 135 | 后续 :没有通知是否给 offer(难道是薪资问题??现在市场要到 20 K左右貌似就要考虑考虑了) 136 | 137 | ## 邻动 138 | 139 | 邻动 这家公司是在 boss 上约的,公司地址也是在知春路附近,公司的办公环境没的说,门口摆着各种零食饮料,面试等待的过程,前台妹子还给了一杯饮料喝,公司主要做视频方向的项目,目前已知产品叫“快牙” 140 | 141 | 第一面 :主要是技术面,基本问的跟之前遇到的问题一样,其中回答的不是很好的问题户要是 MessageQue 的源码实现(我回答错了,应该是链表)还有自定义线程池(应该是问线程池那几个参数),但是公司的技术要求可能希望更倾向于有 FFmpeg 相关经验还有做过视频剪切,裁剪之类的经验吧,问完就送客了....内心其实还是挺喜欢做视频这块的项目 142 | 143 | ## 元宝亿家 144 | 145 | 元宝亿家 这家公司是在 boss 上约的,公司地址在东直门,去了直接在前台填表,然后一个目测像总监的人直接面试,他们现在的项目是采用 MVP 写的应该是想找个人快速接手 146 | 147 | 第一面 :主要是技术面,问的东西感觉还好,但是感觉自己发挥的不是很好,Java String 类的底层源码,Hashmap 实现原理,Android 广播 Service 相关的,ANR,gson 高级用法(比如序列化的时候如何排除某个字段),项目里用到的设计模式,android 手势机制用到了什么设计模式(是责任链模式,这个我回答错了),内存泄漏和内存溢出,子线程不能更新 view 的机制,Rxjava retrofit okhttp,给我印象比较深的是问了 mac 上 pwd 这个命令是干嘛的(我用了这么久mac 确实没有用过这个命令,是显示当前文件全路径的)还有用没用过 Home brew,最后问了问 Git 相关的命令 pull 跟 fetch 148 | 149 | - git rm a.a 移除文件(从暂存区和工作区中删除) 150 | - git rm --cached a.a 移除文件(只从暂存区中删除) 151 | - PS:技术很耐心的给我讲解了我没能答对的问题 152 | - 总结 :感觉自己跟目前市场上需求真正意义的 Android 高级工程职位还是有一定差距的,好多东西还是欠缺好多,还要继续恶补了,fighting... 153 | 154 | 约了第二天复试,信心严重受挫,不知道能不能谈拢... -------------------------------------------------------------------------------- /经验分享/README.md: -------------------------------------------------------------------------------- 1 | ## 经验之谈 2 | 3 | - [一个程序员的血泪史](一个程序员的血泪史.md) 4 | - [我为什么离开锤子科技?](我为什么离开锤子科技?.md) 5 | - [扫清Android面试障碍](扫清Android面试障碍.md) 6 | - [史上最全 Android 面试资料集合](史上最全 Android 面试资料集合) 7 | - [2016年4月某公司面试题及面试流程](2016年4月某公司面试题及面试流程.md) 8 | - [2017届实习生招聘面经](2017届实习生招聘面经.md) 9 | - [国内一线互联网公司内部面试题库](国内一线互联网公司内部面试题库.md) 10 | - [互联网公司面试经验总结](互联网公司面试经验总结.md) 11 | - [一个五年Android开发者百度、阿里、聚美、映客的面试心经](一个五年Android开发者百度、阿里、聚美、映客的面试心经.md) 12 | - [腾讯公司程序员面试题及答案详解](腾讯公司程序员面试题及答案详解.md) 13 | - [面试心得与总结:BAT、网易、蘑菇街 ](面试心得与总结:BAT、网易、蘑菇街 .md) 14 | - [阿里+百度+CVTE面经合集](阿里+百度+CVTE面经合集.md) 15 | - [技术硬碰硬—阳哥带你玩转上海Android招聘市场](技术硬碰硬—阳哥带你玩转上海Android招聘市场.md) -------------------------------------------------------------------------------- /经验分享/一个程序员的血泪史.md: -------------------------------------------------------------------------------- 1 | 我的第一份工作,是某某电力. 2 | 3 | 求职过程很有意思:有一天辅导员有家国企严招聘,说都去看看;结果去了发现只有几个人在,一位大姐说:人都到齐了吗?那就开始吧.我介绍一下我们公司,你们愿意来的话,就填个表. 完全没有面试….就算是有了第一份工作. 4 | 5 | 毕业后就去报到了,结果报到时间还没到…玩了几个月才又去.简单地培训了两个星期,做了一个安全生产知识的考试,就给所有人买了火车票,送到了四川一个偏僻的小山沟里.那里有一家火力发电场正在修建. 6 | 7 | 初到这里,什么也没有.有一片正在修建的房子,刚盖好框架,封了顶,地面都还没有平整,这就是我们的宿舍.每人发了几百块钱,说,开车带你们去镇上买点生活用品吧(工地上有不少的大小货车).然后生活就这样开始了. 8 | 9 | 规定的上班时间是8点到5点;天气非常热,经常只能在屋子里猫着.还好我们不需要天天下工地.有一段时间比较无聊,每天打游戏,但是没有网,只能打单机版的大菠萝.有的日子也经常需要加班赶进度,因为进入梅雨季度了施工就会受影响;但是我们这些质检岗位是帮不上忙的,我们的日子,是负责编质检报表,厚厚的报告拿过来手写上质检记录,反正师傅让这么填的,天知道有没有真正的检查过…. 10 | 11 | 工地上,一般是不允许夫妻同行的,整个工地上几乎全是一水的大老爷们.下了班,业余生活就基本可以用吃喝嫖赌来概括.当然,我们刚毕业的学生,也就只能参于一下吃,每天轮流着去小镇上少得可怜的几家餐馆去吃. 12 | 13 | 老师傅们,除了吃喝,还赌.有时候通霄地打麻将.旷工就旷工呗,反正也不会怎么样.辛苦钱,还算可观,加上各种补贴,安全奖金啊,其实不算少.那两个月七七八八加起来是3500一个月,但是在这山里,基本没地儿花.当然,后来因为每天轮流请客大吃大喝,花光了. 14 | 15 | 当然,还有嫖.谁谁谁去嫖了,基本不是新闻.没办法,没别的娱乐…. 16 | 17 | 到这里一个星期的时候,有天在外面吃完晚饭,有位师傅说,你们要不要我带你们去找个小姐?几个刚毕业的孩子吓尿了. 18 | 19 | 打那后,我就决定要辞职.我觉得要不了几年,我就会成为这样一个人. 20 | 21 | 于是,在工地上又呆了两个月,辞职了. 22 | 23 | 在家玩了一段时间,春节过后,我带着仅剩的1000块钱来到了这个有着几千万人的大城市.(我打肿脸充胖子,给了家里一点钱…) 24 | 25 | 不再是电焊质检工程师,我的新职业是PHP工程师,月薪2500.买了火车票,还剩下700块.住在一个380一个月的地下室.然后中午在公司吃,早晚都吃那种北京的一块钱的大饼,当时感叹,北方的大饼真大啊…. 26 | 27 | 来了没多久,老板说要招人,一直没招着.我想起有一个兄弟,因为没有拿到毕业证,还呆在学校旁边,没有正经找工作,好像呆在一个什么地方打杂,一个月500.我说,把他招过来吧.然后就是哥俩一起住地下室. 28 | 29 | 公司很小,偶尔会晚一点发工资.有一天,有个人离职,走的时候对老板哭着说,我500块的时候就跟着你干 ,干了3年,没要求地啥,你给我什么? 那之后不久,我也换了一家公司. 30 | 31 | 这次换了之后,看起来公司会靠谱一点,因为有某知名网站的CTO坐阵.但是那时候显示鉴别水平太低了…这段时间里其实一直被教育,你的努力,老板看得见.但是事实是,老板看见了,就只会开心一下而已,又能怎么样呢….我从来没想过为自己争取点什么. 32 | 33 | 新的公司,老板同时还有房地产业务和广告公司业务.租的地方很宽敞的样子,搞了个神秘气派的会议室,三天两头拉着据说是政府高官来开会,老板也总是一幅指点江山的样子,说是在通州弄了片地搞开发,但从没见过有啥进展.广告公司呢,好奇葩,是个清华美女负责的,是老板的…小三. 34 | 35 | 广告公司在18楼,有几个设计师,我认识一个,高高瘦瘦的男孩,我悄悄打听了一下,他的月薪是….1400! 36 | 37 | 后来的离开也有戏剧性,有一天快下班时候,来了几个警察,有几个律师来了.原来是有老板们的分歧,都说公司是自己的,要我把服务器代码复制出来交出来,要是交给另一方的话,要告我侵占公司财产…. 38 | 39 | 得,我写个代码还要写进监狱啊,那我辞职还不好吗….. 40 | 41 | 我又失业了. 42 | 43 | 这次,我一定要找个更靠谱的人介绍个工作. 44 | 45 | 所以,我找了一个我认识的某知名博客网站的php开发经理介绍,当时他刚刚要离开,去南京创办一家在线旅游网站(没几年就美股上市了) 46 | 47 | 大牛介绍的工作,从名字上绝对靠谱,是某某电视台的网络中心.在农村小镇,你要说你是这电视台来的啊,镇长马上得来请你吃饭. 48 | 49 | 面试过程也简单:你是介绍过来的呀,那不用面了.你期望月薪多少?8000?好吧,没问题,现在还在职吗?不在职?那你下周一就来吧. 50 | 51 | 入职是在月底了,没过几天,有个妹子拿了个表过来登记身份证号,然后两天后就发了5000块钱现金.我心想,这国家单位就是不一样啊….我才上了几天班,就发钱了… 没几个月我就知道,这是劳务费.我们根本不属于编制人员.编制,是在这个单位的生命线.有编制,你就不用干活,有活让外包做就行了.几乎每周都有各种公司来讲方案,而编制类的老大们就只是做决定,买哪个系统. 这里做点事很难.会议很多,效率很低,很讲究级别.有个会议,一个总监没空去,叫一个下属去代开.进门就被轰了出来:你什么级别啊,这是你能来的会吗? 52 | 53 | 当时是离奥运还有一年四个月,我们的工作就是上线一个相关的站点,要在离奥运一年前上线.还好时间快到的时候,上线了. 54 | 55 | 接下来的几个月,一直没有发工资,连劳动合同也没有,当然,这之前两家也都没有.期间问了几次,但没答复.有次问急了,就安排去一个考试,还是北京人事局组织的,我没考不过,因为考的是政治和英语.没有英语专八和考研辅导是没指望的. 56 | 57 | 我和那个登记身份证的妹子熟了起来.我问她,你发工资了吗?她说,这几个月还没有呢,我算实习.我大学在比利时上的,这边不认.所以我只能在这实习,好把档案挂这.我说,那一个月多少钱?200. 我目瞪口呆.依你开的车,200就够养一天吧? 妹子说,我来上班是为了有点事情做,也不是为了钱. 58 | 59 | 好吧,你家住王府井,你开A6上班,我可不是,我老家房子都摇摇欲坠随时要塌了,我上班做事就是为了钱. 60 | 61 | 我打电话给当时负责的大部分的老大,我诚恳地希望能结一部分钱.他在电话里说,你不是在找人打听吗?听说你不是要走吗?你牛B你就走啊? 我录了音,但后几年之后觉得已经没什么必要了.丑陋的人到处有,犯不着揭开那些不痛快的记忆. 62 | 63 | 我决定去申请劳动仲裁. 我问那位大哥,你介绍我过去,我去申请劳动仲裁,会对你有什么不好的影响吗? 他说,你放心去吧,干活拿钱,天经地义. 64 | 65 | 其实,我也没啥选择,人总得吃饭.要不然我怎么办,兜里没钱了,难道滚回老家去种地吗? 66 | 67 | 2007年,我在劳动局大厅犹豫了5分钟,在想,要不要问问,我可不可以满足那个”农民工免仲裁费”的条件呢? 68 | 69 | 一个月后,开庭. 我见识了各种无赖的狡辩.比如说,现在说,他是实习生,实习生没有工资(已经毕业的就不再是实习生了),现在已经过了60天的诉讼时限了(完幸书记官看了一下日历,我提交材料的时候刚好是第60天). 70 | 71 | 我已经忘了是当庭宣布了结果还是后来通知了. 只记得,是电视台的法务通知我去找财务领钱.去的时候各种忐忑,心想平时找各位头们可是千辛万苦, 这次能顺利吗? 72 | 73 | 还好,财务已经等在那里,数完钱,签字走人. 回来后,法务打电话给我,很生气,不想见你. 我心里想,我已经不生气了,我再也不想和贵台有任何交集. 74 | 75 | 这次之后,我终于换到了一家靠谱的外企,虽然没几年他也从中国互联网中出局了. 76 | 77 | 记我那些可怕的职业经历. 78 | 79 | 原文链接:http://blogread.cn/it/article/7712?f=wb -------------------------------------------------------------------------------- /经验分享/互联网巨头BAT3内部员工的真实状况.md: -------------------------------------------------------------------------------- 1 | 【导读】在中国互联网竞争加剧,让巨头们对用户的竞争很激烈,对人才的竞争更激烈。中国4家市值超过100亿美元的互联网巨头公司BAT3,对待员工的方式,以及组织架构都各有不同,因此造成了各自风格鲜明的企业文化,究竟巨头内部员工生活工作状态如何,是什么原因造成这种情况的,值得我们实地考察一番。本文整理自“每日CEO说”。 2 | 3 | ![](https://img1.doubanio.com/view/note/large/public/p9627597.jpg) 4 | 5 | 阿里巴巴员工:我感觉我是在为自己做事,不是为公司 6 | 7 | 王小炜(虾米网创始人,原阿里巴巴员工):阿里巴巴有强大的HR体系,我目前我在国内看到效率最高的体系。整个HR体系几乎每一件具体的事情都有办法和具体落实的流程,具体到战略怎么制订,目标怎么样分解,考核的指标定的是不是准确等,这都是HR的事情。而对于人的方面所有的业务主管,基本上业绩只占到我们的50%,有30%是团队,还有20%是文化。 8 | 9 | 阿里巴巴是所有互联网巨头中最喜欢给员工灌输价值观、营造企业文化的公司。“江湖”传言阿里的人,工程师都被洗脑,很多猎头也表示阿里的人最难挖。马云一直强调要有自己的DNA,同时也强调value的重要性,同时有一句话让人关注,一万人的believe就是信仰。他能把自己的梦想和价值观源源不断地灌输给你,用其“扭曲磁场”使得你产生认同并与之共同努力。对于不懂技术的领导者而言,他不会跟你坐下来讨论技术问题或者产品问题,他更像是一种精神存在,一盏指明灯,告诉你要往哪里走。这样的文化收获了什么?某位阿里员工表示:“阿里巴巴也没有宗教式的崇拜,我们崇拜的是自己,崇拜自己的事业。”阿里员工难挖,很重要的一点是因为他们认为在阿里是在为自己做事情,当然,阿里巴巴工资高也是不争的事实。 10 | 11 | 百度员工:推崇狼性,公司内部压力太大 12 | 13 | 3B大战之后,百度在内部反思中提出要推广狼性文化,要求员工要以结果导向。百度一些老员工说,“在百度比较怕的是新人,老员工和新员工永远在一个起跑线上在竞争,论功劳,不论苦劳,优秀人才可以不拘一格地被提拔上去。对于新人而言,这是一个很好的竞争环境;然而对于老员工而言,来自内部的竞争压力未免也太大了。” 14 | 15 | 对于竞争激烈的互联网公司而言,提倡狼性文化完全无可厚非,但是这种狼性应该体现在对问题的处理、竞争对手争夺中,要干劲求结果;对内部也狼,就很不人性了。百度的狼性文化让所有员工都保持了一颗时刻学习的心,也把很多老员工推向了竞争对手的怀里。 16 | 17 | 360员工:进公司容易出去难 18 | 19 | 某位360在职员工表示,在360:“做错了不会被开掉,甚至由于管理机制的松散也不会被记录在案,但一顿痛骂是在所难免的。这种暴力的风格像病毒一样自上而下传下来,每一级的Leader都被深深传染,大家都充满戾气,对下属犯的哪怕很小的错误都很容易大发雷霆、说脏话、拍桌子甚至摔东西。除了周鸿祎身边的极少数人,其他人都时常被骂得狗血喷头,颜面扫地。” 20 | 21 | 不过,360也有很多优点,否则早就招不到人了。360跟水浒梁山很像的一点还在于:即便你是小喽啰,也可能天天看到宋江——周鸿祎。该员工还表示:“360的上级会像家长那样,对个人表现出极大的关心,老周会突然跑到你身后看着你的电脑屏幕拍拍肩膀问你最近怎么样?离开时随手拿起你桌上的零食边走边吃。”如果你觉得这是老周信任你的表现,那你可就大错特错了。因为“周鸿祎则压根儿就从来没信任过底下人,对总监以下(包括任职期限不长的很多总监)都是进行信息屏蔽的。” 22 | 23 | 在这样的文化下,新人可能因为周鸿祎突然的一个问候产生有存在感,也可能因为一次狗血淋头的批骂而甩手走人。新人可以随时打破规则与流程做出成绩,但是一年多以后就会因为信任天花板感到迷茫。而当你迷茫想走时,梁山泊的特质再一次显现了:“任何一个员工要跳槽都要经过几道关口的反复盘问,一直要谈到齐向东,如果在比较重要的岗位,周鸿祎会亲自约谈。去哪里?为什么要走?对什么不满?待遇提高一些是否愿意留下来?如果发现你是要去竞争对手阵营就会更难放行。如果你是真的不喜欢这里或有非常好的选择决意离开,就会非常麻烦。据说需要签很多约束性文件,让你感到跳槽风险很大,弄得就像离一次婚一样,麻烦到让你最后放弃跳槽为止。” 24 | 25 | 腾讯员工:注重对我的培养,却不懂得如何留住我 26 | 27 | 曾就职于腾讯的董先生说:“腾讯内部环境氛围都不错,待遇上也不错,整体员工素质也很高。”在腾讯的企业文化里,对员工的发展坚守的是“重视员工成长”,如果你是毕业生,在腾讯的工作幸福度将会非常高。原因是“你可以参加新生培训,同时还可以接触到强势的平台资源。大量的新人虽然是刚刚毕业做产品,哪怕全新做一个产品,在QQ tips和其他交叉推广资源的拉动下瞬间用户量过百万那是常事。这样的成就感是在其他公司比较难享受到的。” 28 | 29 | 问题是:对于新人而言,腾讯的架构太成熟了,在这里个人的价值被平台价值掩盖,因此不少新人还是会选择离开腾讯,原因很简单,在这找不到自己曾经梦想的那种激情。 于是,新人刚刚成熟后,也想要离职;但是对比360的层层盘问,在腾讯想走人则轻松的多。董先生他的领导重金挖过来的人才,但是在最后的离职面谈中,HR更像是例行公事,并没有做深入沟通。这样一来,腾讯花在员工培训上的成果很可能是为他人做嫁衣裳。因此,腾讯的企业文化看起来很好,但是如何落到实处很重要。 -------------------------------------------------------------------------------- /经验分享/史上最全 Android 面试资料集合.md: -------------------------------------------------------------------------------- 1 | ![](img/面试.jpg) 2 | 3 | 最近看到很多人都在找工作, 而且很多人都感觉今年找工作比去年难很多, 竞争力也增加不少, 因此激发我整理这份资料, 希望能帮到正在找或者准备找工作的童鞋们. 4 | 5 | 首先我们能否获得一个面试机会, 那肯定是从简历开始, 简历需要做好功夫, 一份好的简历才足够吸引企业得到面试机会, 接着就是面试了, 面试前必须要先做好准备, 多看一下前辈们总结面试题, 有哪一方面不足的地方赶紧补充一下, 还有要了解一下你即将面试那家公司. 6 | 7 | > 感谢[@Android开发日常](http://weibo.com/AndroidDevDaily)(专注分享 Android 优质开源项目以及高质量开发资料) 支持 8 | 9 | ### 教你写简历 10 | 11 | - [你真的会写简历么?](http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&mid=402970472&idx=1&sn=b9738c66fb5750c2515d57357c01a83f&scene=21#wechat_redirect) 12 | - [80% 以上简历都是不合格的](http://j.codekk.com/blogs/detail/5705bcdf4a38205862ef4770) 13 | - [推荐两个技术简历模板](http://j.codekk.com/blogs/detail/5705bcdf4a38205862ef476f) 14 | - [精益技术简历之道——改善技术简历的 47 条原则](http://lucida.me/blog/lean-technical-resume/) 15 | - [关于程序员求职简历](https://mdluo.github.io/blog/about-resume/) 16 | - [程序员简历模板列表](https://github.com/geekcompany/ResumeSample) 17 | 18 | ### 面试题 19 | 20 | - [国内一线互联网公司内部面试题库](https://github.com/JackyAndroid/AndroidInterview-Q-A) 21 | - [Android 开发工程师面试指南](https://github.com/GeniusVJR/LearningNotes) 22 | - [一个五年 Android 开发者百度, 阿里, 聚美, 映客的面试心经](http://gdky005.com/2016/07/08/%E4%B8%80%E4%B8%AA%E4%BA%94%E5%B9%B4Android%E5%BC%80%E5%8F%91%E8%80%85%E7%99%BE%E5%BA%A6%E3%80%81%E9%98%BF%E9%87%8C%E3%80%81%E8%81%9A%E7%BE%8E%E3%80%81%E6%98%A0%E5%AE%A2%E7%9A%84%E9%9D%A2%E8%AF%95%E5%BF%83%E7%BB%8F/) 23 | - [整理常见 Android 面试问题](https://github.com/leerduo/InterviewQuestion) 24 | - [2016 Android 某公司面试题](http://yuweiguocn.github.io/2016/04/13/interview-2016-big-company/) 25 | - [面试后的总结](http://kymjs.com/code/2016/03/08/01/) 26 | - [Android 面试题整理](http://www.jianshu.com/p/a22450882af2) 27 | - [Android interview questions for 2-5 yrs experienced](http://androidquestions.quora.com/Android-interview-questions-for-2-5-yrs-experienced) 28 | - [Android interview questions](http://androidquestions.quora.com/Android-interview-questions) 29 | - [40 个 Android 面试题](http://www.devstore.cn/essay/essayInfo/7195.html) 30 | - [Android 名企面试题及涉及知识点整理](https://github.com/Mr-YangCheng/ForAndroidInterview) 31 | - [亲爱的面试官,这个我可没看过!(Android部分)](http://www.jianshu.com/p/89f19d67b348) 32 | 33 | ### 做题 34 | 35 | 看完面试题之后那就来做一下面试题目吧, 目前找到两个网站 36 | 37 | - [SillGun](http://skillgun.com/android/interview-questions-and-answers)(国外网站, 自备梯子) 38 | - [牛客网](http://www.nowcoder.com/) 39 | 40 | ### 聊面试 41 | 42 | [(帅张)stormzhang](http://stormzhang.com/) 跟你谈一下面试那些事儿 43 | 44 | - [面试时企业最看中你什么能力?](http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&mid=2650661810&idx=1&sn=f8c1ca67527459db3189a978f0e44cef&scene=23&srcid=08101MZAPzGR1MC1C577enim#rd) 45 | - [我面试到底问什么?](https://zhuanlan.zhihu.com/p/21343656?refer=stormzhang) 46 | - [Android 面试那些事儿](https://zhuanlan.zhihu.com/p/21565914?refer=stormzhang) 47 | 48 | ### 知乎讨论 49 | 50 | - [面试时, 问哪些问题能试出一个 Android 应用开发者真正的水平?](https://www.zhihu.com/question/19765032) 51 | - [我用个假简历去面试 android 的结果为什么会这样?](https://www.zhihu.com/question/38982159) 52 | - [怎么准备Android面试?](https://www.zhihu.com/question/37483907) 53 | 54 | ### 互联网招聘平台 55 | 56 | - [拉勾-专注互联网职业机会](http://www.lagou.com/) 57 | - [简寻-让职位推荐更精准](https://jianxun.io/) 58 | - [100 offer-帮最好的互联网人发现更好的offer](https://100offer.com/) 59 | - [BOSS 直聘-互联网招聘神器](https://www.bosszhipin.com/home/#index) 60 | - [LinkedIn (领英)](https://www.linkedin.com/) 61 | - [哪上班](https://www.nashangban.com/) 62 | 63 | ### 感谢 64 | 65 | 非常感谢上面分享面试资料以及面试经验的前辈们! 66 | 有前辈在前面带路, 我们后辈真心感到幸福. 67 | 68 | ### 祝福 69 | 70 | 最后祝正在找工作的的童鞋们, 马到成功, 心想事成, 事事如意! 71 | 72 | > 原文链接:G军仔,http://www.jianshu.com/p/d1efe2f31b6d -------------------------------------------------------------------------------- /经验分享/工作三年后,我选择离开腾讯.md: -------------------------------------------------------------------------------- 1 | > 来源:微信公众号「LJ 说」,id:「LjNotes」。 2 | 3 | “你居然要从腾讯离职了!?” 4 | 5 | 这是身边朋友得知我要离开后的反应,似乎大家都难以理解这样的决定。 6 | 7 | 从行业环境来看,中国互联网正处于一派繁荣之境;从公司形势来看,也正要准备大刀阔斧地干一番大事业;从个人发展来看,自己在公司也会担任越来越重要的角色。 8 | 9 | 所有的环境都是好的,更加显得离职的决策不理智。 10 | 11 | HR 系统弹窗给出最后的挽留:你确定要提交离职申请吗? 12 | 13 | 经过各种综合考虑后,我还是点了“确定”按钮,正式从工作了三年的腾讯离职。 14 | 15 | 一直有朋友问,在腾讯的工作感觉怎么样? 16 | 17 | 关于这个问题,从来没有好好思考过,觉得当局者迷,尽量做好手上工作就是了。 18 | 19 | 现在终于有时间梳理一番。 20 | 21 | 回想起这几年的经历,既有取得成就的喜悦,也有遭受挫折的失落,个中唏嘘,在离开之际,希望与你分享一二。 22 | 23 | ## 大公司之病 24 | 25 | ![img](../assets/腾讯.png) 26 | 27 | 3 年前,我面试完,从腾讯出来,融入了深南大道熙熙攘攘的下班人群中。 28 | 29 | 在过天桥的时候,我特意拍了一张腾大的夜景,留作纪念,表示我终于要到腾讯上班了。 30 | 31 | 虽然还没正式通知,不过凭着面试反馈,我知道自己终究还是要进入这家梦寐已久的公司了。 32 | 33 | 3 年后,同样是腾讯大厦,我站的位置已经发生改变。 34 | 35 | 从外面的仰望变成了里面的远眺,心情体会也随之改变。 36 | 37 | 只要在大型企业工作过的人,都会被大公司病深深困扰着。 38 | 39 | ### 你厉害还是平台厉害 40 | 41 | BAT 的光环是非常牛逼的,它意味着你进入国内任何一家互联网公司都畅通无阻,它意味着你可以对外分享自己的经验和心得,享受着他人崇拜的目光。 42 | 43 | 然而,在一家几万人的巨头企业,几乎每个人都是一个普通员工,毫无存在感可言,其中滋味就如人饮水,冷暖自知。 44 | 45 | 看《权利的游戏》,我在想,龙妈拥有三条喷火巨龙,为什么还要四处斡旋、拉帮结派,直接骑着三条龙到处喷火,不早就征服七大王国了吗。 46 | 47 | 直到有一幕场景,大龙“Drogo”在斗兽场,被很多小兵拿着矛乱刺,身受重伤,我才反应过来,不管龙妈和她的三条龙再厉害,始终赢不了训练有素的军队。 48 | 49 | 这就是大企业的一个缩影。 50 | 51 | 公司征战,并不需要一个能斗天斗地的英雄,而是需要一支能打仗的队伍。 52 | 53 | 尽管在招聘的时候,大公司往往会筛选出最厉害的一批人,但这并不代表着每个人都举足轻重。 54 | 55 | 事实上,不管你是清北名校毕业光环加持,还是二三本拼搏多年进入大平台,公司想要的结果其实都一样。 56 | 57 | 公司希望每个一线的员工坚守着自己一亩三分地,不需要你把控全局,不需要你战略思考,只要努力地当好螺丝钉。 58 | 59 | 每个人手上分到一小块工作,然后在未来的很长一段时间内,不断地重复着这个工作,成为这个小模块的“专家”。 60 | 61 | 负责个性化皮肤的,可能几年内都在钻研怎么把更多皮肤卖出去;写文案的,长年累月地追着微博热点写文章;做渠道运营的,风雨无阻地盯着各个渠道把自己的广告上线…… 62 | 63 | 并不是说公司不重视个人创造力,恰恰相反,公司希望的是大家发挥创造力,把自己变成更可靠的螺丝钉,成为一个更靠谱的零部件。 64 | 65 | 全公司上下形成一股合力,用军队的方式赢得战争。 66 | 67 | 赢的方式,不是靠武艺高超的英雄,而是让所有人在统一指挥下,移动、格挡、举矛、刺杀,每个动作都如此简单,但千军万马在一起,就能击破对手。 68 | 69 | 这也就意味着铁打的营盘流水的兵,在大平台工作,一件事情成功之后,很容易让人觉得是因为自己牛逼,其实真正的原因是平台的力量。 70 | 71 | 同一件事情,放张三能做成,放李四也 OK。 72 | 73 | 在这里,你不是英雄,你是一个日夜训练着重复动作的小兵。更可悲的是,对于绝大部分人而言,公司压根没计划让你成为一个英雄或将军。 74 | 75 | 你只是千军万马中的一员,平台缺少了你,马上能找到一个人填补上去,而你一旦离开了平台,就会发现很难再复制以往的成功。 76 | 77 | ### 无尽的流程和制度 78 | 79 | 把大象放进冰箱一共要三步:打开冰箱门、放进大象、关上冰箱门。 80 | 81 | 但是在大公司,这个流程就远不止三步了。 82 | 83 | 你要给个报告写清楚把大象放到冰箱的意义和重要性,搞清楚哪种冰箱放哪种大象,把开门动作、放大象的路线描绘清楚,把关门的力度写出来,拿着完整的方案找项目经理去排期,直到有人力来把大象放进冰箱。 84 | 85 | 一个产品或功能,从无到有需要经历漫长的流程。一个大企业的员工,每天为制度所困。 86 | 87 | 某些产品一两年内都没有可感知的外观变化,例如微信,有人就会问这么多工作人员都在忙些什么呢。 88 | 89 | 其实工作人员都很忙,忙在了“流程”和“制度”上。 90 | 91 | 当你们是一个三五人的创业团队,大家就坐在一起,有事情吼一声就可以。比如说想要做一个功能改变,可能就是抬起头跟对面的开发说要怎么怎么改,半天之后就能在产品上看到了。线上反馈好,就保留,反馈不好就改回来,不过是几个小时的事情。 92 | 93 | 然而,对于一个巨型产品来说,所有人的 80% 精力并不是在做“正经的工作”。 94 | 95 | 每个产品经理电脑上都躺着十几份写好的需求文档,在等候着漫长的项目排期。等排期终于到了的时候,有的需求已经不再适用了,或者写它的产品经理已经走了,要是需求和人都还在的话,那就要谢天谢地,守得云开见明月,终于要上线了。 96 | 97 | 每个开发脑子里都存放着许多改进方案,很多可能就是改一行代码的事情,但是不能擅自改动,所有的改动都应该以产品需求为主,否则出了问题那就闯大祸了。 98 | 99 | 遇到跨团队、跨部门沟通,更加是考验人的忍耐力,找一个接口人要花上大半天。对方要么不回复,要么回一句“这不是我负责的”。好不容易对接上了,好家伙,群里面出现四五个接口人,每个人都得交待一遍来龙去脉。 100 | 101 | 除此之外,每个人身上还背负着各种会议、分享、周报月报,PPT 模板成了最受欢迎的文件。 102 | 103 | 能够安心写代码、写需求的时间,算下来也许还真的没有20%。但工作还是要完成的,于是就只好加班加班,成为了互联网行业的一大特色。 104 | 105 | 流程制度是一个好东西,也是一个坏东西。 106 | 107 | 好的地方在于保证企业这条大船高效率地运转,坏的地方在于牺牲了个人效率来满足集体的效率。 108 | 109 | ### 逃不过的修罗场 110 | 111 | 对于大企业工作的朋友,是万万不能问什么时候升职的。就像不能问魏忠贤魏公公什么时候生个小孩,这是要杀头的大罪。 112 | 113 | 越是受过高等教育的人,越是想着要改变世界。当初怀着远大的志向进入大公司,想要施展拳脚做一件不凡的事情。 114 | 115 | 但几年后,大多数人的志气早已被磨消。修身齐家治国平天下,他们连修身都做不好。 116 | 117 | 眼看着身边的朋友在中小公司鹤立鸡群,一路扶摇直上,成为有决策权的管理者,而自己只是数年如一日地坐在小隔间,每周想着如何跟老板汇报工作。 118 | 119 | 也许离 CEO 的办公室只有十米不到的距离,也许每天还能跟几个高管寒暄一下,似乎离他们好近,但是心里明白这种阶层的差距是一道无法逾越的鸿沟。 120 | 121 | HR 在设计个人发展体系的时候,给每个人都提供了两种路径,一个是专业能力晋级,一个是管理职能晋升。 122 | 123 | 所有人都能在专业能力通道上一步步地打怪升级,最终成为高级产品经理、高级工程师,甚至专家 xx。 124 | 125 | 但是在管理通道上,坑位就那么几个,而且大企业内具有管理头衔的人流动性远远低于普通员工,于是国企中“一个萝卜一个坑”的现象在创新的互联网企业同样存在。 126 | 127 | 不少人已经工作十多年,但仍然是一线普通员工。 128 | 129 | 至于谁能晋升,这个话题,不说也罢。 130 | 131 | 要是运气不好,赶上了“宫廷大戏”,轻则工作上举步维艰,重则随着失败一方的领导一起离开。 132 | 133 | 这里就是一个几万人的修罗场,陷于其中的人,个个都身不由己。 134 | 135 | ## 外面的世界很精彩? 136 | 137 | ![img](../assets/腾讯2.jpg) 138 | 139 | 前面说了那么多,你可能会以为我在痛陈大公司的弊端,但这并非我本意。 140 | 141 | 我并没有在真正意义上的创业团队工作过,但也有过小团队的经历,加上平时和不少创业团队的朋友交流,对小公司的辛酸也是略知一二。总结起来,不过是几个字:人少事杂、管理混乱、野蛮生长。 142 | 143 | ### 人少事杂 144 | 145 | 在小团队,可能出现最多的头衔是“全栈 xx”,这并不是说明他有多厉害,而是在一个人手不足的团队中,每个人可能都身兼数职。 146 | 147 | 写前端页面的,可能没人把写好的接口交给你,而是需要自己写服务器脚本、自己调优数据库,还得自己盯着运维数据,宕机了得马上修复。 148 | 149 | 做产品的,不是只打开 word 来写需求文档,用户调研、交互图得自己做,上线后的运营还得自己跟。 150 | 151 | 做运营的,更加是无所不包,大到策划一个线上活动,小到做客服回答用户的咨询。 152 | 153 | 每个人也很忙,似乎什么都能做。 154 | 155 | 这也是小团队吸引人的噱头,能对付过来的人,就成为一个真正的“全栈”,疲于奔命的人,就什么都做什么都学不精。 156 | 157 | ### 管理混乱 158 | 159 | 小团队是否意味着效率高呢,其实也可能存在更加胡乱的管理。 160 | 161 | 曾听朋友讲过他的经历。一个普通员工,需要同时向两个领导汇报,而两个领导还经常互掐,于是该朋友就一脸懵逼了,经常接收到两个完全相反的指令。 162 | 163 | 还有可能,前一周刚刚跟另外一个团队开完会,达成决定做个方案,下周再找他们就发现整个团队被老板裁撤了。 164 | 165 | 又或者,团队在短时间内爆发性增长,为了融资,为了数字,找来了一批新人,大家都面面相觑,不知道谁该做什么,本来公司也并不是因为业务需要而招新人,所以干脆大家都逛淘宝、刷微博。 166 | 167 | 如果说大公司内部的身不由己还有章可循,小公司的变化就是充满着惊喜。 168 | 169 | ### 野蛮生长 170 | 171 | 大公司令人艳羡的地方就是有很多现成的基础服务,而在小团队干活的人都会非常痛苦,大多时候都需要自己造轮子。 172 | 173 | CDN 网络需要自己搭建,大数据平台需要自己开发,账号体系需要自己建设,支付系统需要从零开始…… 174 | 175 | 一个最简单的例子,大公司有成熟的数据体系,每个可以看各种各样的报表,以便调整运营策略,但是小团队可能看个数据就需要提导数据的需求,等到一两周之后才能看到。 176 | 177 | 从一片荒芜中把业务从零开始做起来,是一件很锻炼人的事情,但其实背后更多的是资源浪费。 178 | 179 | ## 都是围城 180 | 181 | ![img](../assets/腾讯3.jpg) 182 | 183 | 万物皆有裂痕,要看到裂痕中照进来的光,而不是裂痕本身。 184 | 185 | 一位长者曾说过,一个人的命运啊,当然要靠自我奋斗,但也要考虑到历史进程。 186 | 187 | 历史的进程和外部的环境,都是我们所不能控制的,但是说到自我奋斗的话,大公司却提供了温暖的襁褓。 188 | 189 | ### 在正规化中成长 190 | 191 | 流程制度的反面就是“正规化”。 192 | 193 | 当有人问我要不要去大公司的时候,我都会回答,如果有合适的机会就去吧。不为别的,就为了体验这种正规化的流程制度。 194 | 195 | 管理两三个人的时候可以靠命令,管理二三十个人的时候可以凭个人魅力,管理几百人、上万人就只能依赖于流程制度了。 196 | 197 | 前面说过流程是牺牲个人效率满足集体效率,从个人成长而言,依然能从中学习到受益终身的东西。 198 | 199 | 你可以知道一个业务从零到一是怎么搭建团队的,各个团队通过什么样的流程进行配合,各司其职代表着每个环节都能产出精品,于是你就知道一个优秀的作品应该是怎么样的,以后碰到类似的场景就有经验了。 200 | 201 | 总而言之,身处在“正规军”当中,虽然自己只是其中的普通一员,但是也可以耳濡目染地学习到最顶尖的产品是如何打造出来的。 202 | 203 | 当然,前提是你有心去了解和学习。 204 | 205 | ### 站在巨人肩膀上 206 | 207 | 大公司汇聚了最优秀的资源,包括人才、技术、资金、经验等。 208 | 209 | 在平时,如果你想了解或钻研某一事物,往往能在内网上找到独家优质的经验分享。 210 | 211 | 更进一步,可以直接联系这个领域的高手咨询请教。内部使用的软件,上至 CEO 下至电脑维修小哥,都静静地躺在好友列表里,等着你联系。 212 | 213 | 在大公司工作的人,是真正的能做到聚焦于业务逻辑本身,而不用被琐碎的杂事打扰。 214 | 215 | 行政上,公司配备了饭堂、班车、体检、节假日福利、家人福利等等,让你能安心地工作。 216 | 217 | 业务上,有专门的基础服务部门,IT设备、开发组件、大数据平台、安全防御、用户数据等等,都可以拿来马上用。 218 | 219 | 个人成长上,虽然不是每个人都能平步青云,但是完善的薪酬福利让每个人都能获得相对合理的回报,各种培训让大家都能适当跳出舒适区获得成长。 220 | 221 | 这些基础服务都是十多年无数人的心血积累,可想而知,站在这样一个巨人的肩膀上,新人可以获得更高速的成长。 222 | 223 | ### 围城里外的人 224 | 225 | 前段时间见到一位大学好友,在外闯荡多年,辗转了几个公司,现在已经是带着小团队的“总监”。 226 | 227 | 我说,这几年间你升职加薪,走上人生巅峰,让人好生羡慕啊。最重要的是可以根据自己想法去实施一些方案,而不会被束手束脚,跟随着高速成长的公司也能让自己的思维和能力快速成长。 228 | 229 | 而他谈到小公司的经历,眼中难掩失落,反而羡慕大公司内提供的坚实后盾。更让我惊讶的是他其实已经在找BAT的机会,准备年后就进入巨头企业了,即使放弃管理者的头衔做一个普通员工。 230 | 231 | 所以你看啊,大公司就是一座围城,外面的人想进去,里面的人想出来。 232 | 233 | 而他们想进去或想出来的原因,其实都是一样的东西。 -------------------------------------------------------------------------------- /经验分享/我为什么离开锤子科技?.md: -------------------------------------------------------------------------------- 1 | 我在2015年3月入职锤子科技,最近几天离职,现在特别想把这不到两年的时间里的经历和我对这家公司的想法写下来。最近一段时间公司发生了大面积的裁员,但是我并不属于这一次陆陆续续的裁员的范围,而是自己提出离职的,最后发生了一些不愉快的事情,后面也会提到。 2 | 3 | 我2012年本科毕业的时候对自己要去什么样的公司完全没有概念,我的专业是软件工程,但是当时不想去任何一家IT 公司,于是我选择了出国留学。锤子科技是2012年5月份创立的,我在大学期间是一名典型的罗粉,但就是这样我还是没有太关心这家由老罗创立的公司,心里甚至觉得老罗有玩票的嫌疑,而且那个时候出国的手续基本办完了,所以也有点行色匆匆的意思,就没有特别关注这家公司。 4 | 5 | 锤子科技的第一个ROM是在2013年3月份发布的,当时人在国外,全程看了发布会的回放,我第一时间刷了这个ROM,虽然问题多多,但是非常喜欢这个系统的很多细节。我第一次动念头想要去锤子科技上班是T1 发布会之后,当时T1 发布之后我也是属于第一批预定的用户。因为我是南方人,回国后找工作简历直接先投了锤子科技,因为如果不行,我是不太可能来北京工作的。当然从面试到最后入职都很顺利,我入职的时候差不多是T2 这个项目刚开始的时候。说到当时入职锤子科技我还是比较感激公司的,因为这是我的第一份工作,之前没有任何Android 相关的开发经验。入职之后知道公司在当时项目非常紧张,需要来了就能干活的人·。想到公司愿意招我这个新人,我心里是有几分侥幸和感谢的。 6 | 7 | 锤子科技在科技圈的公司里可能算名气比较大的企业了,对于它的各种说法和想法都很多,这两年时间确实和公司一起经历了很多。但是在这个时候我最想提的一个点是公司的一次营销活动,就是让大家参与进来以“天生骄傲”为题写一些自己天生骄傲的经历。我觉得这个可能是这个公司最吸引我的点,也是我作为一个罗粉,老罗最吸引我的点,就是有一种永远要做正确的事情的骄傲。 8 | 9 | 我还记得的一个“天生骄傲”的故事是老罗转发的一则,一个人因为工作原因用车很多,他开的是自己的车但是公司会给他报油费,他每次会特别留心记下哪些是因为工作原因用车,哪些不是,每次向公司报销的时候,会去掉平时非工作用车的里程数。·我记得原作者的表达要更让我震撼一些,我自己转述的有点啰嗦,反正意思是差不多的。刚到公司那一会我的确相信这是一家天生骄傲的公司,并且可能是由内而外的,并不简单是公司的营销策略。 10 | 11 | 因为就我当时的观察,来锤子科技入职的同事,有一部分是和我一样的罗粉,他们可能是被相同的价值观吸引来的。还有一部分在入职之前并不知道老罗是谁,但是加入公司之后对这种价值观是很认同的,当然这肯定不包括所有的同事,但我想在我入职那会儿应该包括了大部分同事。但是现在是不是这样,甚至是否公司还能相信自己天生骄傲,我都是不敢确信的。 12 | 13 | 我一直觉得,我的性格是那种,如果在有选择自由的情况下,还愿意做自己不喜欢做的事情,那肯定是有一种我认为正确的价值观或者理想之类的东西在激励我,我相信这也是很多人的情况。我在锤子科技工作的第一年,有一段时间项目特别紧,几乎每天都要工作到9 到10 点钟。我是很不喜欢加班的,工作做完都是想尽早回家做自己的事情,毕竟工作这么忙了,难得有时间干自己喜欢干的事情,说白了我理解的工作就是自己生活的保障,并没有什么特别大的野心要在并不是自己兴趣的工作上有什么作为。虽然这样,只要是觉得有必要在当天做完的工作,不管到多晚我都会做完的,当时让我有这种决心的,可能就是那种对公司的认同感。 14 | 15 | 我入职的时候,面试我的软件副总裁是跟我说过公司的工作时间制度的,锤子科技是采用那种弹性工作制,虽然有一个规定的早十点到晚七点的工作时间,但是只要能保证工作做完,并不强制一定要十点到,七点走,但是如果规定时间内工作做不完,就得自觉加班。这是当时面试我的软件这一块的副总裁原话跟我说的。 16 | 17 | 说实话,我当时对这种工作制度的想法是很理想化的,非常认同,并且也是这么做的。刚入职那会安排我的工作是先理解代码,看文档,刚开始的一周我基本晚上都是7 点准时走,说实话一天时间里有些代码我翻来覆去能看两三遍,基本也都能看懂,而且我也不觉得再多看一两个小时效果会好,毕竟按我学习东西的节奏我不想一天时间看太多东西。但是第二周我们20几个人的组的经理马上找我谈话了,我立刻就意识到有些事情可能并不是我想象的那样,不过他最后给出的理由我也算勉强接受了,他给的理由是要和组里的同事保持步调一致,不然可能有时候找不到你。当然在之后差不多两年的工作时间里,我慢慢对弹性工作制的认识从理想化的状态变成了公司不愿意给加班费,因为所谓的弹性工作制就是一种可以让你每天加班到10点但是不用付薪水的制度。 18 | 19 | 关于工作时间,甚至做到了你没事情做也得在公司待着的地步,感觉就是如果7 点准时走会有人不爽,而这个不爽的人就是我们软件部门实际的负责人,这个人后来升到了软件副总裁的位置,在他升上去之前有些东西还处于含含糊糊的地带,等到他升上去了之后这些都变成了实质的制度。顺便一说,我在公司的两年多时间,弹性工作制从来都是从7 点往后弹的,这倒不是说我们真的有多忙,只是如果你每天的工作时间恰好只有9 个小时,那就会有人找你谈话,不管你的工作做没做完,做得好不好。 20 | 21 | 当然我还是愿意相信公司的很多同事是从理想化的角度来理解弹性工作制的,包括当时面试我的前副总裁,他是一位很和蔼的中年大叔,大概好像几个月前退休了。可是为什么在我眼里公司慢慢变得不那么骄傲了呢?甚至我现在确信公司已经不再有脸面在自己内部员工面前说我们是一家天生骄傲的公司了,为什么会变呢?这可能得好好说一说我们这个组的经理,从他可能能侧面说明这个问题的原因。 22 | 23 | 我们的这位经理是在原来他的经理升上去之后被提拔的,可能就是所谓的自己人吧,但是这个人到底能力怎么样,我觉得可能公司并没有明确考核过,或者甚至本身就没有考核这一步吧,毕竟我对公司管理不是很清楚。我们的软件组里其实并没有明确区分技术和管理的Leader,可以理解为我们的经理需要兼顾这两个方面的工作。 24 | 25 | 我们组大概维护手机软件部分的大大小小几个模块,锤子的软件部分可以说是很出彩的,但是说我们公司软件的技术多么牛逼,我真不敢说,因为我们的工作主要在于实现产品提出的需求,所以只要能实现了产品功能和性能上的需求,并没有人在意你是怎么实现的,至少我们组完全没有所谓软件架构,如果你负责的某一个小模块需要实现一个新需求,那么从设计方案到软件架构到coding很有可能都是你一个人完成的,公司很有可能没有第二个人知道你是怎么实现的。 26 | 27 | 这里说一下在我眼里我们组的经理每天的工作似乎就是满足于不挨他上级的骂,所以像整个组的bug 数量和新需求是否超期这些敏感数据是他最关心的。经常遇到的情况是,有一些bug 比较不好分析,或者需要仔细分析前因后果再做合理修改,但是他会在你分析bug 期间催你,经常用到的句式是:“某某,你那个bug 优先级比较高,快点看一下”,好像我们没有在看一样。而且有时候为了降低bug 数量,他还要经常帮我们解bug,有时候他不好意思让我们来加班,自己周六跑到公司解bug,然后我们周一来了发现他解得不对还要帮他擦屁股。倒不是说他技术有多差,只是组里那么多模块的代码他并不都熟悉。只要当天bug 数量降低了,他就满意了。不过话又说回来帮组里同事解bug 也算是他完成他技术Leader的工作吧。 28 | 29 | 另外虽然他是大组经理,但是其实下面按模块还是分了几个小组的,一般小组内的工作都是我们组长分的。我们小组组长的方式我是很认同的,有的时候他并不会主动给我们分bug,我们会自己从他那里取,这种方法看似放任,但其实我们组长是基于对我们的了解以及建立在这种了解之上的信任才这么做的,这种方式和公司的弹性工作制本质上是类似的,我觉得我们小组内这样合作的方式是很合适并且效率很高的。然而我们这位经理经常越过我们组长给我们分bug,有的时候他不太了解我们组内工作的分配,这样分bug反而会给组内同事造成困扰和压力。在工作的这几年时间内,我们的经理似乎对我们完全没有什么具体的了解,只是象征性的组织过几次团建,吃过几次饭而已。 30 | 31 | 我想这对他做管理方面的工作是很致命的,因为他要做的不只是每天催我们尽快解bug 而已。也有很多同事为他解释,说他是工程师出生,人又内向,所以有时候表达不到位,但是我想说的是,既然这样,他为什么能做20 几个人团队的经理?他似乎只是作为一个单向的通道存在,项目催的紧了,他就也来催我们一下。其实问题可能很简单,因为他是自己人,有的时候看到他被骂心里其实也很难受,但是这样能力的人当上经理,可能也是从侧面反映了,为什么我越来越感到公司不那么天生骄傲了。 32 | 33 | 我写这些的目的是很明确的,字里行间都能看出我是带着对公司管理层的怨恨的,因为他们可能就是锤子科技变成今天这样的罪魁祸首。这里说一下我离职的原因,今年公司软件团建的时候采取了很幼稚的形式(发小学的时候用的那种大红奖状,完了竟然没有奖金)奖励了一些加班时间最多,解bug数量最多的同事,我对这样的价值取向是很不认同的,因为这对不用加班就可以把工作做完甚至做得更好的同事是不公平的。 34 | 35 | 借着酒劲,我在公司群里说了很难听的话,顺便在当晚老罗和我们互动的微信群里问了过年红包还会不会发,结果是直接被退群。当然我后来很后悔,本来年后我也打算离职回老家了,还是忍一忍的好,毕竟后面经历的事情都非常荒诞。我再到公司的时候发现我的办公电脑被收走了,据说公司邮箱也被封了,据说是经理怕我再做出可怕的事情说出可怕的话。但是公司HR对我说公司的正常裁员已经结束了,也不会开我,这里我真想说难道让我把电脑搬回来继续干吗?我实在没有心力和公司耗下去,就自己提了离职。 36 | 37 | 我在职期间有一次经理找我聊天问我为什么最近工作不积极对公司有什么不满,我主要对他说了两点,一是公司取消本来就屈指可数的中秋节红包福利为什么不在公司层面通知一下(我和同事等了一天发红包,虽然锤科福利不多,但是逢年过节是直接给现金红包的,每次领红包都很开心),二是公司裁员为什么采取遮遮掩掩的态度,因为即使你不说外面的人一样知道,反而如果你对内部员工都不开诚布公,却会造成我们的恐慌和懈怠。 38 | 39 | 经理的答复是,这个不可能按你想象得那么理想化的,其他公司都是这样的。其实从他这番话也大概能了解为什么公司在做出这些决定的时候是这样的态度,因为公司的管理层似乎都被他这样的人占领了,他这句话在我看来好像就是锤子科技变得不再特殊的宣言吧。这里想告诉那些还想来锤子科技入职的朋友,了解一家公司不能光看公司自己的官博。 40 | 41 | 其实最后我还想说一句,锤子科技没有做错任何事情,因为站在公司角度来看,简直可以用为了盈利把所有问题都说通,但是这家公司已经不能再公开宣称自己天生骄傲了。也许正是被天生骄傲的价值观吸引来的,在离开的时候看清公司的现状才不会有任何遗憾。 -------------------------------------------------------------------------------- /经验分享/我为什么要离开华为?.md: -------------------------------------------------------------------------------- 1 | > 原文链接:微信公众号[小李成长笔记] 2 | 3 | 到 9 月中旬,我在华为工作就满 6 年了。 4 | 5 | 同事听说我要离职,都很诧异。干的好好的啊,怎么突然说要走? 6 | 7 | 是啊,在现在的部门这么久了,人和事都很熟了,偶然有些小摩擦,都可以理解和接受。那为什么要走? 8 | 9 | 华为的 34,胶片文化,强绩效主义,部门墙,研发的低效等等这些,大家说过很多,就不再重复了。在我看来,这些都是微不足道的外因,我完全不认同,但可以理解。 10 | 11 | 真正推动我下定决心离开的还是内因:我那颗躁动不安的心。 12 | 13 | 在华为 3 年后,工作真的变成了工作。我常常想不起来昨天都做了些什么,只是模糊记得接了几个电话,帮助客户解决了几个问题,接入了几个莫名其妙的会议,回复了几个邮件。就这样一周过去了,一个月过去了,一年也过去了... 14 | 15 | 职级在升,工资在涨,年终奖也一年比一年多。可我却越来越心虚,越来越焦虑。 16 | 17 | 有 2 个我一直在争辩。一个我:现实点,这就是份工作,出卖时间,换取工资而已。干嘛期望那么多?另一个我:还这么年轻,就认命了吗。想想这些年你都干了些啥。每天处理些 stupid 问题,一年年重复自己,你还想像这样过多少年? 18 | 19 | 2 个我不停的争吵,日子在争吵中慢慢过去。 20 | 21 | 我知道不能再这样下去了,我要行动起来。我要做准备,离开这个安逸,不再成长的环境。 22 | 23 | ## 学习 Andoid 开发,重拾开发乐趣 24 | 25 | 16 年 Android 很火。我想学 Android 开发,买了《第一行代码》,边看书边搭环境,敲代码。买 vpn,用 google 搜索问题答案。关注了张哥的公众号「stormzhang」,知道了 stackoverflow 网站,github 网站。知道了开源软件。慢慢摸索,年底时也能做个还能用的 app 了。上传到应用商店,看到后台统计数据,每天有上百人下载,也有一些用户评论说不错,很喜欢。感觉很充实,很有成就感。 26 | 27 | ## 走出去,接触外面的世界 28 | 29 | 在华为的日子,每天按部就班工作,大家都很勤奋,专注。只需要埋头干活就可以了。慢慢的,好像和外面的世界隔离了。 30 | 31 | 当我第一次参加一个武汉产品经理交流活动,看到不大的会议室里坐满了上百名自发参加的朋友,被大家渴望知识和交流的态度感动,原来,我们身边还有这样一群人。 32 | 33 | 也参加过几次程序员自发组织的编程活动,大家一起结对编程,分享各自的工作流,推荐好用的工具和软件。能感受到他们对自己工作的热爱,让我羡慕感动。大周末的,放弃陪老婆孩子的休息时间,穿越大半个城市,和一群素未谋面的伙伴编程,绝对的真爱。当然,我们也成了网上的好朋友,虽然平时不咋联系,但大家知道,我们都是一类人。 34 | 35 | ## 关注互联网大 V,了解另一个世界 36 | 37 | 这期间关注了好多互联网行业大v的公众号。有耿直风趣的冯大辉,温和幽默的 MacTalk,黑白灰道都熟的 Caoz,硅谷 Airbnb 美女程序员 angena,Android 开发者帅比 stormzhang...每天看他们的文章,看他们写自己的从业感悟,写互联网行业的灰与黑,写曾经的迷茫和奋斗...真实有力,催人奋发。牛人都在奋斗,我还在温室里等死。 38 | 39 | ## 偶遇付费社群,见识网赚套路开眼界 40 | 41 | 转眼到了 17 年,好像一夜之间,知识付费就火了起来。 42 | 43 | 机缘巧合之下,加入了网友亦仁的生财有道小密圈,亲身经历了圈主 30 天收百万入圈费,见识圈主高超的运营手法,圈友大牛们分享的各种生财,吸粉套路。彻底改变了我对广告,对一些互联网业务的认知。 44 | 45 | 以往的我,对各种广告很不屑,认为都是骗人的。ppt 教程,excel 教程,这么 low 的东西,我可是 it 专家,哪看的上这些... 46 | 47 | 选择性无视,不看,不听,不想。 48 | 49 | 现在我会去想为什么会有这个,有多大市场,针对哪些人群,它们有哪些套路,有哪些值得学习的地方?这个事情有哪些门槛,如果我去做,可以吗。 50 | 51 | 脑袋瓜被慢慢的打开,不再是以前那个非黑即白,只有 0 和 1 的工科男死脑筋了。 52 | 53 | 还加入了刘大猫的财富移动城堡。了解到刘大猫,是看了他写的自传文,一个从高中开始就做网站,做淘宝客,做流量变现,27 岁就积累千万财富的大牛人。听他分享各种总结,经验和看法,思路清晰,态度诚恳。不满足现状,完全放弃还很赚钱的淘宝客生意,坚决转型公司和个人发展方向。让我汗颜,想到自己畏惧风险,待在舒适圈里不愿出来,无地自容。 54 | 55 | 还有好多社群,这些社群让我有了“近距离”观察和交流大牛的机会。他们就像存在你身边,就是你的一个学长或者朋友,你好像看着他们一步步成长为大牛,有时候会想,或许有一天,我也会牛起来。 56 | 57 | ## 开发微信小程序,体验流量的威力 58 | 59 | 网上和群友交流,不能光说不练,你总得有些拿的出手的东西。听再多的套路,经验不如亲自去实践下。 60 | 61 | 趁着小程序这股东风,自学开发了一个文字转语音的小工具。从 app 名的选择,简介,到搜索关键词,app 界面,功能都做了一些思考。开发上线后,收集用户反馈,和用户交流使用场景,慢慢的每天用户竟然有近 300 了,排名也一直上升到第一名。 62 | 63 | 有天看后台数据,访问量突然增加了 10 倍,当天新增用户 3.5 k。吓坏了,以为后台出统计故障了。原来是知晓程序公众号当天的文章推荐了。那天好多用户联系我,夸工具好用,确实帮他们解决了一些问题。好开心,体验了一把网红的感觉。 64 | 65 | ## 以后咋发展 66 | 67 | 写到这里,可能很多朋友会问,你写了这么多瞎折腾的经历,和你离职到底有啥关系呢,是要转行搞互联网产品开发吗?老实说,我也不肯定。 68 | 69 | 我只知道这些经历潜移默化改变了我,让我不再封闭,不再纠结。我庆幸这些经历让现在的我经过华为近 6 年的“摧残”后,心还火热,对未来还留有希望。 70 | 71 | 工作咋办呢,32 岁“高龄”了,还要去做程序员吗,还有公司要吗?没事,我觉得自己还年轻,如何做产品,还有很多可以学,我也相信,华为 6 年的经历,磨练,纠结,折腾,这些都是我未来宝贵的财富。 72 | 73 | 终于,我做了选择,不再纠结,重新出发。 -------------------------------------------------------------------------------- /经验分享/杭州找 Android 工作的点点滴滴.md: -------------------------------------------------------------------------------- 1 | ## 写在前面的话 2 | 3 | 我从 14 年毕业到现在一直待一个三线城市,就用 C 市 代替吧。地方很小,适合居住,但不适合 it 开发,城市很小、圈子很小,it 不发达,想要在 it 上面有出路的还是得去北上广深大城市。我在这个城市呆了三年左右由于自己的一些私事所以趁机就出来想找个大城市呆呆,原本打算去其他城市的,后来稀里糊涂的来到了杭州,在朋友这呆了半个月,直到找到工作。我是 17 年 3 月 25 号就辞职了,递交了辞职申请之后然后就跑去云南玩了一圈之后才想到要找工作的,然后就来杭州了,以上就是大概背景,接下来就写写关于在杭州找一份关于 Android 开发的工作中所遇到的人和事,不看不知道,原来世界真的很大各种人都有,果真印证了一句话:林子大了,什么鸟都有。 4 | 5 | ## 简历 6 | 7 | 面试之前,当然得准备一份简历啦,我的简历是当年刚毕业的时候写的一份简历,这里面用到的模板是 [乔布简历]() http://cv.qiaobutang.com/ 里面的简历模板不错(哈哈,这不是给它打广告的,我一直用这个,感觉不错就推荐了)。简历模板找到了,下面就是内容了,俗话说,要想找到好工作,一个好的简历必不可少的。因为公司越大的话,投递的人肯定越多,HR 筛选的时间就少了,所以简历有亮点就能打动HR,这样才能有面试资格,有了这个面试资格后才有可能得到这个工作机会,有的人写了简历投给公司后,就像石沉大海一样,毫无音讯,所以,如果有小伙伴,投了简历但是没有回应,不妨修改一下简历,但这里修改简历不是要你去造假,这里面有个梗,待会说~,写完了简历,接下来就是投简历了,有几个渠道可以找工作: 8 | 9 | - 内推,内推的质量是最高的,但也是最难的。 10 | - 第三方招聘网站,如 拉钩,51Job,智联招聘,猎聘同道等。 11 | 12 | 就以我而言,使用上面四种方式进行对比,拉勾网上面公司质量还是不错的,但是HR筛选简历这关有点问题,里面给出的筛选不通过理由都是一样的。51job 和智联招聘两者类似,都差不多,我就是在智联招聘上面找到工作的。猎聘同道里面猎头比较多,我第一次面试就是上面的猎头进行联系的。总的而言,前三个多投投简历,重点放在智联招聘和拉勾网上面,其他也可以稍微投投~ 13 | 14 | ## 面试 15 | 16 | 经过上面简历这个步骤,相信我们能够接到一些公司的面试邀请的,在接受公司面试邀请之前,我们得复习面试中所遇到的一些基本知识,主要有 Java 和 Android 这两方面的面试知识。 17 | 18 | - Java 基础知识,主要有面向对象三大特性及理解,接口与抽象类、泛型、线程池、集合框架、设计模式、常用算法等知识点。 19 | - Android 知识,主要就是一些常用的知识,待会儿给出一些链接。 20 | 21 | 以上是专业知识准备,还得准备一些其他人文方面的知识,譬如自我介绍啊、兴趣爱好啊之类的。 22 | 23 | 有了上面的知识基础,我们就可以上面进行面对面接触啦,我总共大概用了 10 天左右时间,面试了大概 15 家公司,其中有三家是明确拒绝我的,还有四家是我明确拒绝他的,还有几家我对比了一下,然后选择了一个性价比比较高的公司的。在这些公司里面,花样百出,有的公司不知道怎么想的,想花一年工作经验的工资找一个三年工作经验的人,这是典型的想得美。还有的公司忽悠你,就是变相的让你加班,我问他工资能给多少,他说看你能力而定,能力多大,工资多高,我说具体个数,如果我面试通过了,你能不能给我准确的数,他就不说话了,而且是早上 10 点上班,晚上 9 点下班,呵呵,不评价,忽悠应届生呢吧~ 24 | 25 | 印象最深的一家公司,地址是 https://www.lagou.com/gongsi/191783.html 没错,里面的评论就是我评论的,刚进去,给人的感觉,公司环境还不错,宽敞明亮的,然后 HR 给了我 A4 纸,正反面,填写个人的信息,详细程度令人咋舌。好不容易花了几分钟填完之后又给我整整三张面试题,没错,是整整三张,题目很多很多,让我做,哎,我也好忽悠,第一次碰到这种情况,所以就按部就班老老实实的做完了,花了 20 分钟,做之前还把我的手机给收了,娘的,当成学校考试呢啊???更奇葩的还在后面,做完面试题目之后,就开始了面试,那个面试官好像是子公司分责人吧,类似于总经理吧,看着我的简历,竟然问我有没有造假???WTF!!!还跟我说,他要想查的话很快就能查到了,我就无语了,我的简历竟然能让他怀疑我造假了,我的简历是有多雷人啊!!!接着就开始问我各种知识点,回答出来 95 以上吧,有几个平时没接触过,所以不知道怎么回答,最后面试结束了,没什么问题就开始讨论工资的问题,他看了我的期望薪水,问我,为什么翻了一倍?我跟他说,我以前呆的城市,非常小,基本连三线都不到,房价只有几千块,跟杭州能比吗???然后他就无语了,我就问他,为什么杭州房价比 C 房价高出 4~5 倍,你还想工资都差不多???面试简章上面的薪水范围跟实际给出的范围严重不符,我估计这家公司就是想把人先忽悠过去,然后开始各种压价,这太他么的可耻了,最后果断被我给拒绝了,而且是当面拒绝,没有留有情面,给再多也不会去的,这是情怀问题,感觉对程序员不尊重!!!以后大伙找公司,注意这家公司,过来人的经验~ 26 | 27 | 上面就是我遇到的印象比较深刻的一家公司。接下来我们就来总结一下面试过程中提出的各种问题,如果有需要的小伙伴可以参考一下。 28 | 29 | ## 面试问题 30 | 31 | ### 关于人文方面的问题 32 | 33 | - 先介绍一下你自己? 34 | - 你有什么兴趣爱好? 35 | - 你平常空闲时间会干什么,看哪些书,有什么心得体会? 36 | - 你为什么要从上家公司离职? 37 | - 如果面试过了的话,就会问你的期望薪资,然后就开始各种压榨你。 38 | 39 | ### 关于 Java 方面的问到的知识点 40 | 41 | - 面向对象的三大特性,如何理解其中的多态? 42 | - JVM 的内存模型? 43 | - String、StringBuilder、StringBuffer 的区别,StringBuffer 是如何实现线程安全的? 44 | - 了解过 HTTP 吗?说说它的特点,它里面有哪些方法,有了解过吗?知道 HTTPS 吗?这两者有什么区别? 45 | - 你平常是怎么进行加密的?MD5 加密是可逆的吗? 46 | - 接口与抽象类的区别?static 方法可以被覆盖吗?为什么? 47 | - 创建线程的方式,他们有什么区别?知道线程池吗?说说对线程池的理解? 48 | - 你了解过 Java 的四种引用吗?分别代表什么含义,他们有什么区别? 49 | - Java 中关于 equals 和 hashcode 的理解? 50 | - 关于 Java 中深拷贝和浅拷贝的区别? 51 | - 简单的说下 Java 的垃圾回收? 52 | - 了解过 Java 的集合吗?说说 HashMap 的底层实现原理?ArrayList 和 LinkedList 的区别?Java 集合中哪些是线程安全的? 53 | - 如何实现对象的排序? 54 | - 知道 ThreadLocal 吗?说说对它的理解? 55 | - 在你写代码的过程中有使用过设计模式吗?你知道哪些?为什么要这样用,能解决什么问题? 56 | - 了解注解吗?了解反射吗?为什么要使用反射? 57 | - 数据结构中常用排序算法? 58 | 59 | 以上就是关于 Java 所问道的知识点,记得不是太清楚了,待补充。。。 60 | 61 | ### 关于 Android 方面的问到的知识点 62 | 63 | - Activity 的生命周期是什么? onPause 和 onStop 有什么区别? 64 | - Android 五种布局的性能对比? 65 | - Android 四大组件是什么?分别说说对它们的理解? 66 | - 关于 Service 的理解?它的启动方式有什么区别? 67 | - 了解 fragment 吗?说说你对它的理解? 68 | - 自定义过 view 吗?它的步骤是什么?说说你自定义 view 过程中出现的问题,以及是如何解决的? 69 | - 刷新 view 的几种方式,他们有什么区别? 70 | - Android 实现数据存储的几种方式? 71 | - 如何实现 Android 中的缓存的,通过使用第三方库和自定义来分别说明一下缓存技术的实现? 72 | - 如何实现 Activity 与 fragment 的通信? 73 | - Android 5.0、6.0、7.0 新特性? 74 | - Android 中的动画分类? 75 | - 你以前是如何进行屏幕适配的? 76 | - 说说 Activity 创建过程? 77 | - Android 中如何与 JS 交互的? 78 | - 了解 APP 的启动流程? 79 | - 你知道哪些图片加载库?他们有什么区别?ImageLoader 的内部缓存机制是什么?是如何实现的? 80 | - Android 中是如何实现异步通信的? 81 | - 说说 Handler 内部实现原理? 82 | - 使用过 AsyncTask 吗?说说它的内部实现原理?它有什么缺陷?如何改进? 83 | - 知道 JNI、Binder 吗?说说你对它们的理解? 84 | - 如何实现进程间的通信? 85 | - 说说 Android view 和 viewGroup 的事件分发机制? 86 | - 你开发过程中使用到了哪些第三方库?了解过他们的源码吗? 87 | - 你了解广播吗?它与 EventBus 有什么区别?能互相实现吗? 88 | - 你们网络请求是如何实现的?知道 Volley 吗?内部实现流程是什么?它与 OKHttp 有什么区别? 89 | - 你了解哪些第三方功能?知道推送吗?它的原理是什么? 90 | - 接触过 MVP 模式吗?说说看对它的认识? 91 | - 知道 Android 中的多渠道打包吗? 92 | - Android 签名机制的原理?反编译解压后的文件夹所包含的内容有哪些? 93 | - 你了解过模块化、组件化开发吗? 94 | - 开始开发 APP 如何进行架构? 95 | - APP 工程模块是如何划分的?你是如何进行封装的? 96 | - APP 是如何进行优化的?知道 OOM 吗?如何解决内存泄漏? 97 | 98 | 以上就是我这次面试过程中涉及到的一些关于 Android 方面的知识点,有点模糊了,全凭记忆,待补充.... 99 | 100 | 经过上面的几个阶段,历时半个月,最终我找到了一家比较心仪的公司,整体的性价比个人感觉比较高,符合我的期望。以上便是我这次来杭州面试的点点滴滴,希望对有需求的小伙伴一些帮助~ 101 | 102 | 请记住一点,薪水并不是唯一所要关注的重点,关键还得看看公司环境、领导、同事相处愉快不愉快?要不然给你再多的薪水,每天干的不爽,那不是很悲哀? 103 | 104 | 最后我会提供一些我面试准备阶段复习所用到的一些基础知识点链接,面试必问的一些基础原理一定得知道,不能含糊,要不然面试过程中必定会露马脚。有需要的小伙伴可以参考一下。 105 | 106 | ## 相关链接 107 | 108 | - [Java面试题集](http://blog.csdn.net/dd864140130/article/details/55833087) 109 | - [Android 名企面试题及涉及知识点整理](https://github.com/Mr-YangCheng/ForAndroidInterview) 110 | - [40个 Android 面试题](http://www.devstore.cn/essay/essayInfo/7195.html) -------------------------------------------------------------------------------- /经验分享/给培训班出来的一点不成熟的小建议.md: -------------------------------------------------------------------------------- 1 | ## 那些IT培训出来的Android工程师,希望你面试时涨点记性 2 | 3 | 这几天,公司在前程无忧上发布了招聘 Andriod 工程师广告。不到 3 个小时, hr 就抱怨说投递 Andriod 工程师的简历已经多达 300 份了。不得已将 Andriod 工程师招聘就下架,然后就去筛选简历了。 4 | 5 | 我也顺便看了看公司的要求,写的很简单,主要有: 6 | 7 | > 经验:1 年以上。 8 | > 9 | > 有开发过蓝牙相关项目经验优先。 10 | > 11 | > 学历:大专及以上。 12 | 13 | 不知道 hr 和部门经理花费了多少时间挑选了 10 个人出来了。然后就预约了他们过来面试。 14 | 15 | 很荣幸,经理让我出一点面试题,还特意嘱咐,毕竟我们是软硬件的方案公司,已经有成熟的架构了。app 的难度不大,只要后面肯学是一样。就把第一轮面试的任务交给我。这里我并不是歧视培训机构出来的 Andriod 工程师,而是这几天面试下来,让我觉得很不可思议。如果有的人再用心一点,或许 offer 就是你的了。也希望不论你是正常毕业出来找工作,还是培训出来,自学的,或者中途转行的,都涨一点记性。 16 | 17 | ### 先说说笔试部分 18 | 19 | 有两道题基本上回答的很令人无语。 20 | 21 | **1、写一写自定义 view 的思路。** 22 | 23 | 有几个人直接写了一个 onMeasure() 方法放那里了,就写了这几个单词,难道就不用多写一点解释。 24 | 25 | 我一看简历的工作经验,不是 2 年,就是 2 年半,还有 3 年的,怎么一个自定义 view 都没有遇到过?真的是让我怀疑你的工作经验是怎么来的。 26 | 27 | 重点是:有一个面试者就直接向我坦诚了自己是培训出来的。我瞬间就恍然了很多。我也是个打工的,没必要去指责他,只是给他讲了讲自定义 view,简历应该如何如何。这哥们居然临走时感谢我,要了我的微信。 28 | 29 | **2、有没有访问过公司官网?如果有,谈谈你的意见。(这一题是 hr 要求加上去的。)** 30 | 31 | 结果很失望,只有 3 个人说访问过。 32 | 33 | 你去别人家公司面试,就不去访问别人一下官网,更何况,你投简历的时候,你就不用看公司简介,上上别人家公司官网。就算你是群投,收到面试通知后,都不用好好准备一下吗?去官网看看公司文化,团队,产品,特别是产品,大概就知道会用到哪些技术。 34 | 35 | ### 再说说口头问的部分 36 | 37 | **1、搞清楚自己的开发工具** 38 | 39 | 1) 请问你现在开发使用的什么工具? 40 | 41 | 面试者:Android Studio 42 | 43 | 2) 那你现在主要使用哪个版本开发? 44 | 45 | 面试者:2.4 46 | 47 | 一瞬间,我直接懵了。Google 才放出正式的 2.3 版本。你就用起 2.4 呢? 后面还补充告诉我,自己去官网下载的,一直在使用 48 | 49 | **2、不要刻意去讨好公司,技术的知识点不确定就不要随便回答。** 50 | 51 | 1) 你在简历上说自己做过蓝牙相关的项目,那你告诉我,一般使用蓝牙需要哪几个权限? 52 | 53 | 面试者:好像两个,两三个吧? 54 | 55 | 2) 那你能不能说一下? 56 | 57 | 面试者:我都是直接复制粘贴的 58 | 59 | 唉,你让我说什么好。你要是做过蓝牙相关开发,哪怕是你忘记了权限,你也可以说一下蓝牙连接的流程。就算以前没做过,招聘的岗位都告诉你了,有做过蓝牙项目 app 的优先,你就可以去补充一下 Andriod 关于蓝牙的知识点啊? 60 | 61 | **3、别把别人上架的 app 当成自己的。** 62 | 63 | 1) 你有没有 app 上架过? 64 | 65 | 面试者:有 66 | 67 | 等他在应用市场找给我的时候,我一看就傻眼了,下载量破 500 万了,一看开发者就不是你。唉,我当时就想,兄弟啊,你没有可以告诉我,就算找一个别人的,能不能不要这么多下载量的?更何况,国内 Andriod 应用市场这么多,想自己的 app 上架都不是什么难事。 68 | 69 | 更可况,面试要求你,也没有说非要你上架 app。毕竟我们公司的 app 的难度还好。 70 | 71 | **4、Andoid 6.0 权限的处理。** 72 | 73 | 1)在实际开发中,你说如何处理 6.0 以上手机权限问题的。 74 | 75 | 面试者:我们开发的 app 不需要适配 6.0 啊。 76 | 77 | 2)要是客户的手机是 6.0 的,客户要求你的 app 项目适配 6.0 的呢? 78 | 79 | 面试者:不会吧,都不用适配 6.0 的 80 | 81 | 你不是都有两三年开发经验了? 6.0 以上权限适配属于最基本的知识。随便说个思路,先申明权限,到用的时候,对高版本手机进行判断撒的……都是可以的,实际开发项目时,又不是不让你上网去学习研究。 82 | 83 | 唉……不知道该怎么说好了! 84 | 85 | 拒绝做面试题的! 86 | 87 | 有两个过来面试的,直接告诉我: 88 | 89 | 我写不好,能不能直接说啊! 90 | 91 | 我也只好同意了,毕竟从那么多简历里面,把你们筛选出来是多么地不容易。结果,好是令人失望。 92 | 93 | 如果你没有过硬的技术,请不要随便拒绝面试题。 94 | 95 | ## 后记 96 | 97 | 那个坦诚告诉我是培训出来的人,晚上发信息告诉我一些信息。 98 | 99 | 他们说 Andriod 面试,不用做题的? 100 | 101 | 现在企业喜欢经验多的,我们都是被要求写几年经验。这样才有面试机会。 102 | 103 | 你们招聘公司职位要求的技术不是随便写的吗? 104 | 105 | 大家都不容易,但是做技术这一行,还是需要硬实力。再怎么包装你有几年经验,拿到面试通知时,为什么不去好好准备面试,去背诵知识点。你连最起码的别人公司的官网都不上,你又有什么话语权? 106 | 107 | 哪怕你没有 app 上过架,确实是刚毕业,转行,或者刚培训出来的,如果临时抱佛脚,复习了公司要求的知识,这个 offer 就属于你的了。毕竟还有 3 个月试用期。 108 | 109 | 不论什么原因让你的简历如何完美,但是还请你的技术能够跟上。我所知道的,同事,朋友做 IT 的,有的是跨专业,有的是高中,有的是培训出来的,既然他们都行,请你也行! -------------------------------------------------------------------------------- /经验分享/腾讯公司程序员面试题及答案详解.md: -------------------------------------------------------------------------------- 1 | 今天给大家带来的是腾讯的面试题,觉得有用的亲,赏个脸,轻点上面蓝色黑马程序员几个字关注我吧! 2 | 3 | **1、腾讯笔试题:const的含义及实现机制const的含义及实现机制,比如:const int i,是怎么做到i只可读的?** 4 | 5 | const用来说明所定义的变量是只读的。 6 | 7 | 这些在编译期间完成,编译器可能使用常数直接替换掉对此变量的引用。 8 | 9 | **2、腾讯笔试题:买200返100优惠券,实际上折扣是多少?** 10 | 11 | 到商店里买200的商品返还100优惠券(可以在本商店代替现金)。请问实际上折扣是多少? 12 | 13 | 由于优惠券可以代替现金,所以可以使用200元优惠券买东西,然后还可以获得100元的优惠券。 14 | 15 | 假设开始时花了x元,那么可以买到 x + x/2 + x/4 + ...的东西。所以实际上折扣是50%.(当然,大部分时候很难一直兑换下去,所以50%是折扣的上限) 如果使用优惠券买东西不能获得新的优惠券,那么总过花去了200元,可以买到200+100元的商品,所以实际折扣为 200/300 = 67%. 16 | 17 | **3、腾讯笔试题:tcp三次握手的过程,accept发生在三次握手哪个阶段?** 18 | 19 | accept发生在三次握手之后。 20 | 21 | 第一次握手:客户端发送syn包(syn=j)到服务器。 22 | 23 | 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。 24 | 25 | 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。 26 | 27 | 三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。 28 | 29 | **4、腾讯笔试题:用UDP协议通讯时怎样得知目标机是否获得了数据包用UDP协议通讯时怎样得知目标机是否获得了数据包?** 30 | 31 | 可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int。 32 | 33 | 发送方在发送数据时将此ID和发送时间记录在本地。 34 | 35 | 接收方在收到数据后将ID再发给发送方作为回应。 36 | 37 | 发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。 38 | 39 | **5、腾讯笔试题:统计论坛在线人数分布 求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每个ID从登陆到退出会向一个日志文件中记下登陆时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。** 40 | 41 | 一天总共有 360024 = 86400秒。 42 | 43 | 定义一个长度为86400的整数数组int delta[86400],每个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。 44 | 45 | 然后依次读入每个用户的登录时间和退出时间,将与登录时间对应的整数值加1,将与退出时间对应的整数值减1。 46 | 47 | 这样处理一遍后数组中存储了每秒中的人数变化情况。 48 | 49 | 定义另外一个长度为86400的整数数组int online_num[86400],每个整数对应这一秒的论坛在线人数。 50 | 51 | 假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0] = delta[0]。第n+1秒的人数online_num[n] = online_num[n-1] + delta[n]。 52 | 53 | 这样我们就获得了一天中任意时间的在线人数。 54 | 55 | **6、腾讯笔试题:从10G个数中找到中数 在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。** 56 | 57 | 不妨假设10G个整数是64bit的。 58 | 59 | 2G内存可以存放256M个64bit整数。 60 | 61 | 我们可以将64bit的整数空间平均分成256M个取值范围,用2G的内存对每个取值范围内出现整数个数进行统计。这样遍历一边10G整数后,我们便知道中数在那个范围内出现,以及这个范围内总共出现了多少个整数。 62 | 63 | 如果中数所在范围出现的整数比较少,我们就可以对这个范围内的整数进行排序,找到中数。如果这个范围内出现的整数比较多,我们还可以采用同样的方法将此范围再次分成多个更小的范围(256M=2^28,所以最多需要3次就可以将此范围缩小到1,也就找到了中数)。 64 | 65 | **7、腾讯笔试题:两个整数集合A和B,求其交集两个整数集合A和B,求其交集。** 66 | 67 | - 读取整数集合A中的整数,将读到的整数插入到map中,并将对应的值设为1。 68 | - 读取整数集合B中的整数,如果该整数在map中并且值为1,则将此数加入到交集当中,并将在map中的对应值改为2。 69 | 70 | 通过更改map中的值,避免了将同样的值输出两次。 71 | 72 | **8、腾讯笔试题:找出1到10w中没有出现的两个数字 有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数?** 73 | 74 | 申请10w个bit的空间,每个bit代表一个数字是否出现过。 75 | 76 | 开始时将这10w个bit都初始化为0,表示所有数字都没有出现过。 77 | 78 | 然后依次读入已经打乱循序的数字,并将对应的bit设为1。 79 | 80 | 当处理完所有数字后,根据为0的bit得出没有出现的数字。 81 | 82 | 首先计算1到10w的和,平方和。 83 | 84 | 然后计算给定数字的和,平方和。 85 | 86 | 两次的到的数字相减,可以得到这两个数字的和,平方和。 87 | 88 | 所以我们有 89 | 90 | x + y = n 91 | 92 | x^2 + y^2 = m 93 | 94 | 解方程可以得到x和y的值。 95 | 96 | **9、腾讯笔试题:需要多少只小白鼠才能在24小时内找到毒药有1000瓶水,其中有一瓶有毒,小白鼠只要尝一点带毒的水24小时后就会死亡,至少要多少只小白鼠才能在24小时时鉴别出那瓶水有毒?** 97 | 98 | 最容易想到的就是用1000只小白鼠,每只喝一瓶。但显然这不是最好答案。 99 | 100 | 既然每只小白鼠喝一瓶不是最好答案,那就应该每只小白鼠喝多瓶。那每只应该喝多少瓶呢? 101 | 102 | 首先让我们换种问法,如果有x只小白鼠,那么24小时内可以从多少瓶水中找出那瓶有毒的? 103 | 104 | 由于每只小白鼠都只有死或者活这两种结果,所以x只小白鼠最大可以表示2^x种结果。如果让每种结果都对应到某瓶水有毒,那么也就可以从2^x瓶水中找到有毒的那瓶水。那如何来实现这种对应关系呢? 105 | 106 | 第一只小白鼠喝第1到2^(x-1)瓶,第二只小白鼠喝第1到第2^(x-2)和第2^(x-1)+1到第2^(x-1) + 2^(x-2)瓶....以此类推。 107 | 108 | 回到此题,总过1000瓶水,所以需要最少10只小白鼠。 109 | 110 | **10、腾讯笔试题:根据上排的数填写下排的数,并满足要求。** 111 | 112 | 根据上排给出十个数,在其下排填出对应的十个数, 要求下排每个数都是上排对应位置的数在下排出现的次数。上排的数:0,1,2,3,4,5,6,7,8,9。 113 | 114 | **11、腾讯笔试题:判断数字是否出现在40亿个数中?** 115 | 116 | 给40亿个不重复的unsigned int的整数,没排过序的,然后再给几个数,如何快速判断这几个数是否在那40亿个数当中? 117 | 118 | 答案:unsigned int 的取值范围是0到2^32-1。我们可以申请连续的2^32/8=512M的内存,用每一个bit对应一个unsigned int数字。首先将512M内存都初始化为0,然后每处理一个数字就将其对应的bit设置为1。当需要查询时,直接找到对应bit,看其值是0还是1即可。 -------------------------------------------------------------------------------- /网络编程/Android客户端和服务端如何使用Token和Session.md: -------------------------------------------------------------------------------- 1 | 对于初学者来说,对Token和Session的使用难免会限于困境,开发过程中知道有这个东西,但却不知道为什么要用他?更不知道其原理,今天我就带大家一起分析分析这东西。 2 | 3 | ## 我们先解释一下他的含义: 4 | 5 | 1、Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。 6 | 7 | 2、Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 8 | 9 | 3、使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。 10 | 11 | 了解了Token的意义后,我们就更明确的知道为什么要用他了。 12 | 13 | ## 如何使用Token? 14 | 15 | 这是本文的重点,在这里我就介绍常用的两种方式。 16 | 17 | 1、用设备号/设备mac地址作为Token(推荐) 18 | 19 | 客户端:客户端在登录的时候获取设备的设备号/mac地址,并将其作为参数传递到服务端。 20 | 21 | 服务端:服务端接收到该参数后,便用一个变量来接收同时将其作为Token保存在数据库,并将该Token设置到session中,客户端每次请求的时候都要统一拦截,并将客户端传递的token和服务器端session中的token进行对比,如果相同则放行,不同则拒绝。 22 | 23 | 分析:此刻客户端和服务器端就统一了一个唯一的标识Token,而且保证了每一个设备拥有了一个唯一的会话。该方法的缺点是客户端需要带设备号/mac地址作为参数传递,而且服务器端还需要保存;优点是客户端不需重新登录,只要登录一次以后一直可以使用,至于超时的问题是有服务器这边来处理,如何处理?若服务器的Token超时后,服务器只需将客户端传递的Token向数据库中查询,同时并赋值给变量Token,如此,Token的超时又重新计时。 24 | 25 | 2、用session值作为Token 26 | 27 | 客户端:客户端只需携带用户名和密码登陆即可。 28 | 29 | 客户端:客户端接收到用户名和密码后并判断,如果正确了就将本地获取sessionID作为Token返回给客户端,客户端以后只需带上请求数据即可。 30 | 31 | 分析:这种方式使用的好处是方便,不用存储数据,但是缺点就是当session过期后,客户端必须重新登录才能进行访问数据。 32 | 33 | ## 使用过程中出现的问题以及解决方案? 34 | 35 | 刚才我们轻松介绍了Token的两种使用方式,但是在使用过程中我们还出现各种问题,Token第一种方法中我们隐藏了一个在网络不好或者并发请求时会导致多次重复提交数据的问题。 36 | 37 | 该问题的解决方案:将session和Token套用,如此便可解决,如何套用呢?请看这段解释: 38 | 39 | ![wKioL1QX85nCkJ5qAABWcdNyC0g731.png](http://s3.51cto.com/wyfs02/M02/49/A9/wKioL1QX85nCkJ5qAABWcdNyC0g731.png) 40 | 41 | 这就是解决重复提交的方案。 42 | 43 | 总结:以上是个人对开发中使用Token和session的一点总结,如有叙述不当之处请指正,我将及时改正并感谢,我知道还有更多更好的使用方式,我在这里只是抛砖引玉,希望大家将您的使用方式提出来,我们一起讨论,学习,一起进步,同时也为像我一样对这方面理解薄弱的朋友提供点帮助,谢谢。 -------------------------------------------------------------------------------- /网络编程/README.md: -------------------------------------------------------------------------------- 1 | ## 网络编程 2 | 3 | - [Android客户端和服务端如何使用Token和Session](Android客户端和服务端如何使用Token和Session.md) 4 | - [推送原理](推送原理.md) 5 | - [阐述一下对XMPP协议理解以及优缺点?](阐述一下对XMPP协议理解以及优缺点?.md) 6 | - [简单阐述一下及时推送原理?](简单阐述一下及时推送原理?.md) -------------------------------------------------------------------------------- /网络编程/推送原理.md: -------------------------------------------------------------------------------- 1 | # 极光推送技术原理:移动无线网络长连接 2 | 3 | ## 移动互联网应用现状 4 | 5 | 因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统 PC 上的应用很大不一样,需要根据手机本身的特点,尽量的节省电量和流量,同时又要尽可能的保证数据能及时到达客户端。 6 | 7 | 为了解决数据同步的问题,在手机平台上,常用的方法有2种。一种是定时去服务器上查询数据,也叫Polling,还有一种手机跟服务器之间维护一个 TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的 Push。 8 | 9 | 从耗费的电量、流量和数据送达的及时性来说,Push 都会有明显的优势,但 Push 的实现和维护成本相对较高。在移动无线网络下维护长连接,相对也有一些技术上的难度。本文试图给大家介绍一下我们[极光推送](http://www.jpush.cn/)在 Android 平台上是如何维护长连接。 10 | 11 | ## 移动无线网络的特点 12 | 13 | 因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。 14 | 15 | ![http://www.cisco.com/en/US/i/100001-200000/110001-120000/119001-120000/119935.jpg](http://www.cisco.com/en/US/i/100001-200000/110001-120000/119001-120000/119935.jpg) 16 | 17 | 图片源自 cisco.com. 18 | 19 | NAT 功能由图中的 GGSN 模块实现。 20 | 21 | 大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。 22 | 23 | ## Android 平台上长连接的实现 24 | 25 | 为了不让 NAT 表失效,我们需要定时的发心跳,以刷新 NAT 表项,避免被淘汰。 26 | 27 | Android 上定时运行任务常用的方法有2种,一种方法用 Timer,另一种是AlarmManager。 28 | 29 | ### Timer 30 | 31 | Android 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。这种方式不能满足我们的需求。 32 | 33 | ### AlarmManager 34 | 35 | AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。 36 | 37 | 这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。极光推送的 Android SDK 就是基于这种技术实现的。 38 | 39 | ## 服务器设计 40 | 41 | 当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。 42 | 43 | 假设一台服务器维护10万个长连接,当有1000万用户量时,需要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题。那就需要我们尽可能提高单台服务器接入用户的量,也就是业界已经讨论很久了的 C10K 问题。 44 | 45 | ### C2000K 46 | 47 | 针对这个问题,我们专门成立了一个项目,命名为C2000K,顾名思义,我们的目标是单机维持200万个长连接。最终我们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接。 48 | 49 | ## 后记 50 | 51 | 稳定维护长连接是推送平台的一个基础,[极光推送团队](http://blog.jpush.cn/)将会在这方面长期投入,以保证用户能有效的节省电量、流量,同时数据能实时送达。 52 | 53 | # 即时通信技术-Websocket 54 | 55 | 以前不管使用HTTP轮询或使用TCP长连接等方式制作在线聊天系统,都有天然缺陷,随着Html5的兴起,其中有一个新的协议WebSocket protocol,可实现浏览器与服务器全双工通信(full-duplex),它可以做到:浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。这个新的协议的特点正好适合这种在线即时通信。 -------------------------------------------------------------------------------- /网络编程/简单阐述一下及时推送原理?.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [极光推送原理配套视频](https://v.qq.com/x/page/h0394a7zioh.html) 48 | - [xmpp基本概念配套视频](https://v.qq.com/x/page/s0394k4p10i.html) 49 | - [配套视频](https://v.qq.com/x/page/h0394s3mc5k.html) 50 | 51 | ## 4-简单阐述一下及时推送原理? 52 | 53 | a) 传统获取服务器数据使用的是pull模式,是客户端向服务器请求数据。从客户端发起连接请求,获取到服务器数据后就关闭连接。当连接断开后,服务器就会失去客户端的地址,因此无法主动向客户端发送消息。 54 | 55 | b) 推送(push)是服务主动向客户端发送数据。 56 | 57 | 它的原理是保持一个长连接,当客户端和服务器建立连接后不再断开,这样服务器随时有新消息都可以发送给客户端。 58 | 59 | 长连接和短连接。所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接。(心跳连接) 60 | 61 | ``` 62 | while(true) { 63 |   request(timeout); 64 |   request(timeout); 65 | } 66 | ``` 67 | 68 | 短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,即每次TCP连接只完成一对 69 | 70 | c) 至于如何获取推送消息。由于服务端传来推送消息的时间是不确定的,这里只能等待推送SDK的回调,比如通过注册监听或者广播接收者。不同的厂商的推送SDK可能会有不同的处理方案,以百度推送SDK来说,是通过广播接收者获取推送数据。 71 | 72 | ## 5-简要说明一下openfire、smack、spark 73 | 74 | openfire是基于XMPP协议的即时通信的服务器端的一个实现,你不需要编写一行服务端的代码,实现一个简单的点对点通信或是简单的群聊. 75 | 76 | smack 是XMPP传输协议的Java实现,提供了一套API接口,可以连接服务端。一般用于快速开发手机客户端。 77 | 78 | spark是基于smack实现的一个XMPP即时通信客户端(PC端的)。 79 | 80 | ## 6-列出几种常见的解决消息即时获取方案 81 | 82 | 1. 轮询(Pull)方式:客户端定时向服务器发送询问消息,一旦服务器有变化则立即同步消息。 83 | 2. SMS(短信消息)(Push)方式:通过拦截SMS消息并且解析消息内容来了解服务器的命令,但这种方式一般用户在经济上很难承受。 84 | 3. 持久连接(Push)方式:客户端和服务器之间建立长久连接,这样就可以实现消息的及时行和实时性。 85 | 86 | ## 7-Timer比AlarmManager实现心跳时更耗电原因 87 | 88 | - Timer 89 | 90 | Android 的 Timer 类可以用来计划需要循环执行的任务。 91 | Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量, 92 | 大大减短手机待机时间。这种方式不能满足我们的需求。 93 | 94 | - AlarmManager 95 | 96 | AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。 97 | 98 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 99 | 100 | 微信公众号名称:Android干货程序员 101 | 102 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /网络编程/阐述一下对XMPP协议理解以及优缺点?.md: -------------------------------------------------------------------------------- 1 | ### 源码分析相关面试题 2 | 3 | - [Volley源码分析](http://www.jianshu.com/p/ec3dc92df581) 4 | - [注解框架实现原理](http://www.jianshu.com/p/20da6d6389e1) 5 | - [okhttp3.0源码分析](http://www.jianshu.com/p/9ed2c2f2a52c) 6 | - [onSaveInstanceState源码分析](http://www.jianshu.com/p/cbf9c3557d64) 7 | - [静默安装和源码编译](http://www.jianshu.com/p/2211a5b3c37f) 8 | 9 | ### Activity相关面试题 10 | 11 | - [保存Activity的状态](http://www.jianshu.com/p/cbf9c3557d64) 12 | 13 | ### 与XMPP相关面试题 14 | 15 | - [XMPP协议优缺点](http://www.jianshu.com/p/2c04ac3c526a) 16 | - [极光消息推送原理](http://www.jianshu.com/p/d88dc66908cf) 17 | 18 | ### 与性能优化相关面试题 19 | 20 | - [内存泄漏和内存溢出区别](http://www.jianshu.com/p/5dd645b05c76) 21 | - [UI优化和线程池实现原理](http://www.jianshu.com/p/c22398f8587f) 22 | - [代码优化](http://www.jianshu.com/p/ebd41eab90df) 23 | - [内存性能分析](http://www.jianshu.com/p/2665c31b9c2f) 24 | - [内存泄漏检测](http://www.jianshu.com/p/1514c7804a06) 25 | - [App启动优化](http://www.jianshu.com/p/f0f73fefdd43) 26 | - [与IPC机制相关面试题](http://www.jianshu.com/p/de4793a4c2d0) 27 | 28 | ### 与登录相关面试题 29 | 30 | - [oauth认证协议原理](http://www.jianshu.com/p/2a6ecbf8d49d) 31 | - [token产生的意义](http://www.jianshu.com/p/9b7ce2d6c195) 32 | - [微信扫一扫实现原理](http://www.jianshu.com/p/a9d1f21bd5e0) 33 | 34 | ### 与开发相关面试题 35 | 36 | - [迭代开发的时候如何向前兼容新旧接口](http://www.jianshu.com/p/cbecadec98de) 37 | - [手把手教你如何解决as jar包冲突](http://www.jianshu.com/p/30fdc391289c) 38 | - [context的原理分析](http://www.jianshu.com/p/2706c13a1769) 39 | - [解决ViewPager.setCurrentItem中间很多页面切换方案](http://www.jianshu.com/p/38ab6d856b56) 40 | 41 | ### 与人事相关面试题 42 | 43 | - [人事面试宝典](http://www.jianshu.com/p/d61b553ff8c9) 44 | 45 | ### 本文配套视频 46 | 47 | - [什么是XMPP配套视频](https://v.qq.com/x/page/t0394w3zhoa.html) 48 | 49 | ## 3-简单阐述一下对XMPP协议理解以及优缺点? 50 | 51 | ### 定义: 52 | 53 | > XMPP(可扩展消息处理现场协议)的前身是Jabber,由一个开源组织产生的即时通信协议,基于可扩展标记语言(XML)的一种协议,是由IETF(国际互联网小组)通过的网络标准。 54 | 55 | - 及时通讯:发送一则消息,对方账号马上即时接收到消息。中间没有出现延时。 56 | 底层使用 socket实现/java对tcp/ip协议的实现 57 | 58 | ### 基本网络结构 59 | 60 | XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,连接管理和信息的路由功能。网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信), 61 | MSN,ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML。 62 | 63 | - 举个例子看看所谓的XML(标准通用标记语言的子集)流是什么样子的? 64 | 65 | 客户端: 66 | 67 | ```xml 68 | 69 | 74 | ``` 75 | 76 | 服务器: 77 | 78 | ```xml 79 | 80 | 86 | ``` 87 | 88 | 其他通信 89 | 客户端: 90 | 91 | ```xml 92 | 95 | Art thou not Romeo, and a Montague? 96 | 97 | ``` 98 | 99 | 服务器: 100 | 101 | ```xml 102 | 105 | Neither, fair saint, if either thee dislike. 106 | 107 | ``` 108 | 109 | 客户端: 110 | 111 | ```xml 112 | 113 | ``` 114 | 115 | 服务器: 116 | 117 | ```xml 118 | 119 | ``` 120 | 121 | - 以文档的观点来看,客户端或服务器发送的所有XML文本连缀在一起,从<stream>到</stream>构成了一个完整的XML文档。其中的stream标签就是所谓的XML Stream。在<stream>与</stream>中间的那些<message>...</message>这样的XML元素就是所谓的XML Stanza(XML节)。 XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的, 122 | 任何时候都有可能从一方发信给另外一方。通信的最后阶段是</stream>关闭流,关闭TCP/IP连接。 123 | 124 | > XMPP 的消息格式。 125 | > XMPP 协议的所有消息都是 XML 格式的,在 XMPP 中定义了 3 个顶层消息: 126 | 127 | - 2.1 Presence 128 | 129 | 用于确定用户的状态。消息结构举例如下(每个 XML 的 node 还会有很多其他 attribute,为了简单起见这里省略,下同): 130 | 131 | ``` 132 | 133 | online 134 | 135 | ``` 136 | 137 | - 2.2 Message 138 | 139 | 用于在两个用户之间发送消息。消息结构举例如下: 140 | 141 | ``` 142 | 143 | hello 144 | 145 | ``` 146 | 147 | - 2.3 IQ​ 148 | 149 | 信息/请求,是一个请求-响应机制,管理XMPP服务器上两个用户的转换,允许他们通过相应的XML格式进行查询和响应。 150 | 151 | ``` 152 | 153 | 154 | ``` 155 | 156 | ![img](http://upload-images.jianshu.io/upload_images/4037105-e929a077d630d27e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 157 | 158 | [及时聊天的展示形式](https://v.qq.com/x/page/k0394y5jo6d.html) 159 | 160 | ![img](http://upload-images.jianshu.io/upload_images/4037105-66c1ec0e265257de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 161 | 162 | ![img](http://upload-images.jianshu.io/upload_images/4037105-9d4319f3ac184fa5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 163 | 164 | > 面向连接:三次握手 165 | 166 | ![img](http://upload-images.jianshu.io/upload_images/4037105-45c525c855b6e407.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 167 | 168 | - 欢迎关注微信公众号,长期推荐技术文章和技术视频 169 | 170 | 微信公众号名称:Android干货程序员 171 | 172 | ![img](http://upload-images.jianshu.io/upload_images/4037105-8f737b5104dd0b5d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -------------------------------------------------------------------------------- /面试技巧/README.md: -------------------------------------------------------------------------------- 1 | ## 面试技巧 2 | 3 | - [程序员面试宝典](程序员面试宝典.md) 4 | - [罗永浩新东方万字求职信](/罗永浩新东方万字求职信.md) 5 | - [我在面试中最喜欢问开发者的问题,和回答思路](我在面试中最喜欢问开发者的问题,和回答思路.md) -------------------------------------------------------------------------------- /面试技巧/我在面试中最喜欢问开发者的问题,和回答思路.md: -------------------------------------------------------------------------------- 1 | 本文作者是 Zach Mathew,他是 FreshBooks 的经理。 2 | 3 | 我面试过很多人,大部分是开发者,部分是产品经理,有时候会面试主管或者副总监。但不管是面试什么级别和什么工种的应聘者,我都会在过程中对他们提出一个相同的要求: 现在,请把我当成一个学生,随便教我点什么东西和知识吧。 4 | 5 | ![img](http://static.codeceo.com/images/2016/03/f48e1a69643f19b48cfcac3a922523e2.jpg) 6 | 7 | 什么都行。 8 | 9 | 可能是什么东西你觉得有意思的,或者你自己在某方面研究比较深的领域。甚至是你最近刚刚学习到的东西,反正是什么都好。你不需要是那方面的专家,但至少能跟我讲明白讲清楚,而且你能够回答我一些基础的问题。 10 | 11 | 对,现在给你十分钟的时间,把你脑海里想到的东西教给我。 12 | 13 | 我之所以对面试者提出这个要求,是因为我想知道我能从这个将来的同事身上学习到什么。我也想知道你的团队未来会从你身上学习到什么。 14 | 15 | 当然,我问这个问题的时候,也想知道你的气质符合不符合我们公司的文化。虽然说 FreshBooks 这个公司并没有具体的规则,但其实每天,无论是实习生或者是管理层,我都会问他们类似问题,而且希望他们能给我满意的回答。 16 | 17 | 以下是我不久前问自己同事的问题,并从中学习到的事情。 18 | 19 | - 我问 Tobi, 他是我团队里的一名开发: 我看到你在代码中正在用 ES6 , 你认为它用起来怎么样? 20 | - 我问 Marcus, 他是金融公司的一名分析师: 跟我解释下同期群分析是什么意思?我应该在未来使用这个方法吗? 21 | 22 | ![img](http://static.codeceo.com/images/2016/03/9c4ad2cb2fcb79c89baa8f06cfa4af33.jpg) 23 | 24 | 有的时候,一些初级开发者会问我:我知道的东西,你肯定早就知道了。我没法教你。 25 | 26 | 不,还是请指点我一下。实际上,当你真正教我的时候,你会吃惊于我多么无知。 而且就算你讲的东西是我早就知道的事情,再听一遍也不是什么大事。 27 | 28 | 毕竟在那么多次的面试里,肯定会有人告诉我一些我早就知道的东西。那真的无所谓,我真正想从面试里了解到的是: 29 | 30 | 1. 你是否能和他人进行有效交流? 31 | 2. 你能否在研究一件事情的时候透过表面深入内层? 32 | 3. 你是否具有有条理阐述一件事情的能力,还是说你是对什么都很不耐烦沟通的人? 33 | 34 | 会学习是一种能力,能把自己学习到的东西表达给别人也是一种能力。 35 | 36 | 这不仅仅是为了面试,我的意图是考察你其他的技能和潜能。 37 | 38 | 在公司内部,我们也经常举办这种「教我点什么」的大会。通常是在周五下午,喝点小酒,大家聚在一起,分享彼此之间从本周工作以及最近的项目中得到的灵感。基本上,这就是一个信息的共享大会。不需要准备 ppt 或者演讲稿什么的,只需要张开嘴,放开心扉,告诉别人你的所得。 39 | 40 | 你也可以反过来,邀请我教你学习点什么。 这当然可以,如果我要求你教我点什么,你也可以对我提出相同要求。面试是一个双方过程,在我评测你的时候,你也可以评价我。 41 | 42 | 所以拜托,当我要求你教我点什么东西的时候,你也可以对我提出相同的请求。 43 | 44 | 上文来源:[Medium](https://medium.com/@zachmathew/the-one-question-i-ask-in-every-interview-66561f69c233#.vhvgl44r3) 45 | 46 | ![img](http://static.codeceo.com/images/2016/03/aa3d8bf54f8e5af3c644313095f059db.jpg) 47 | 48 | 我个人感觉,这种「给你十分钟,你随便教我什么东西」的面试思路非常有意思。那身为应聘者,我们该怎么运用这十分钟给面试官留下好印象呢,对爱丽丝来说,其实觉得把这整个场景视为一个小小的自检是否具有有效沟通的过程比较有意思。 49 | 50 | 我把自己的面试思路分享一下。 51 | 52 | 首先,你要对面试时间有个预估。对方说给你十分钟,这时间说长不长说短不短。你可以迅速规划一下,比如我先用五分钟的时间讲述我想说东西的具体概念、理论知识和背景感悟。然后,剩下五分钟,可以用来让面试官继续提问或者自己继续补充。切不可自己光说。 53 | 54 | 其次,你也可以把自己的打算和规划告诉面试官,比如在我最初前几分钟内向你讲述背景知识的时候,请先听我说完,尽量不要打断我的思路。 55 | 56 | 接着,当你在真正介绍一件事、或传授一个知识的时候,记住一定要有条理,说话慢一些。当回答对方的问题时,多问问对方「我讲清楚没有」,而不是要问对方「你听明白没有」。 57 | 58 | 最后,面试官都说了他其实并不在乎你讲什么。这是什么意思?这就是说你跟他说怎么烙煎饼和怎么解释引力波,人家根本不在乎。其实主要考察你的交流水平,其实也就是逻辑。 59 | 60 | 而逻辑简单来说,就是大到小,从浅及深,想清楚影响的因果联系。当对方提出你不懂的问题,可以把他的问题拆解出几个小问题,去解答你懂得的地方。而对于不懂的事情,也不要不懂装懂,反而可以咨询他的意见——相信我,既然他能问出你不懂的问题,就说明他的水平比你高。 61 | 62 | 让他帮你解释。当面试官比你话多的时候,这绝对是很好的信号。 -------------------------------------------------------------------------------- /面试技巧/罗永浩新东方万字求职信.md: -------------------------------------------------------------------------------- 1 | 俞校长您好: 2 | 3 |   我先对照一下新东方最新的招聘要求: 4 | 5 |   1、有很强的英语水平,英语发音标准 6 | 7 |   英语水平还好,发音非常标准,我得承认比王强老师的发音差一点。很多发音恐怖的人(宋昊、陈圣元之流)也可以是新东方的品牌教师,我不知道为什么要要求这一条,尽管我没这方面的问题。 8 | 9 |   2、大学本科或以上学历,英语专业者优先 10 | 11 |   真不喜欢这么势利的条件,这本来应该是实力、马力之流的学校的要求。 12 | 13 |   3、有过考TOEFL、GRE的经验 14 | 15 |   GRE考过两次。 16 | 17 |   4、有教学经验者,尤其是教过以上科目者优先 18 | 19 |   教过后来被国家明令禁止的传销课,半年。 20 | 21 |   5、口齿伶俐,中文表达能力强,普通话标准 22 | 23 |   岂止伶俐,简直凌厉,普通话十分标准,除了对卷舌音不太在意(如果在意,平舌音也会发错,所以两害相衡取其轻)。 24 | 25 |   6、具备较强的幽默感,上课能生动活泼 26 | 27 |   我会让他们开心。 28 | 29 |   7、具备较强的人生和科学知识,上课能旁征博引 30 | 31 |   除了陈圣元,我在新东方上过课的老师(张旭、王毅峰、王昆嵩)都和文盲差不多,当然他们还小。说到底,陈圣元的全部知识也只是在于让人看不出他没有知识而已。 32 | 33 |   8、具备现代思想和鼓动能力,能引导学员为前途奋斗 34 | 35 |   新东方的学员是最合作,最容易被鼓动的,因为他们来上课的最大目的就是接受鼓动,这个没有问题。 36 | 37 |   9、年龄在40岁以下 38 | 39 |   28岁。 40 | 41 | 下面是我的简历或是自述: 42 | 43 | 罗永浩,男,1972年生于吉林省和龙县龙门公社。 44 | 45 |   在吉林省延吉市读初中时,因为生性狷介,很早就放弃了一些当时我讨厌的主课,比如代数、化学、英文,后来只好靠走关系才进了当地最好的一所高中,这也是我刚正不阿的三十来年里比较罕见的一个污点。因为我和我国教育制度格格不入又不肯妥协,1989年高中二年级的时候就主动退学了。有时候我想其实我远比那些浑浑噩噩地从小学读到硕士博士的人更渴望高等教育,我们都知道钱钟书进清华的时候数学是零分(后来经证实其实是15分),卢冀野入东南大学的时候也是数学零分,臧克家去山东国立青岛大学的时候也是差不多的情况。今天的大学校长们有这样的胸襟吗?当然,发现自己文章写的不如钱钟书是多年后的事情了,还好终于发现了。 46 | 47 |   退学之后基本上我一直都是自我教育(当然我的自我教育远早于退学之前),主要是借助书籍。因为家境还勉勉强强,我得以相对从容地读了几年书,"独与天地精神往来"。 48 | 49 |   基于"知识分子要活得有尊严,就得有点钱"这样的认识(其实主要是因为书价越来越贵),我从1990年至1994年先后筛过沙子,摆过旧书摊,代理过批发市场招商,走私过汽车,做过期货,还以短期旅游身份去韩国销售过中国壮阳药及其他补品。令人难堪的是做过的所有这些都没有让我"有点钱",实际上,和共同挣扎过的大部分朋友们比起来,我还要庆幸我至少没有赔钱。 50 | 51 |   我渐渐意识到我也许不适合经商,对一个以知识分子自许的人来说,这并不是很难接受的事情,除非这同时意味着我将注定贫穷。 52 | 53 |   1994年夏天,我找了个天津中韩合资企业的工作并被派去韩国学习不锈钢金属点焊技术,1995年夏天回国的时候,很不幸我姐姐也转到了这家天津的公司并担任了副总经理,为了避嫌我只好另谋出路。 54 | 55 |   1995年8月至1996年初,经一位做传销公司(上海雅婷)的老同学力邀,我讲了半年左右的传销课,深受广大学员爱戴。遗憾的是国家对这种有争议的商业形式采取的不是整顿而是取缔的政策,所以看到形势不对,我们就在强制命令下达之前主动结束了生意。因为那时候我爱上了西方音乐(古典以外的所有形式),大概收有上千张英文唱片,为了听懂他们在唱些什么,我在讲传销课的同时开始学习一度深恶痛绝的英文。我在一个本地的三流私立英语学校上了三个月的基础英语课,后来因为他们巧立名目拒付曾经答应给我的奖金(我去法院起诉过,又被法院硬立名目拒绝受理),我只好又自学了。 56 | 57 |   实在不知道困在一个小地方可以做些什么,所以1996年夏天我到天津安顿下来(那时候我很喜欢北京,但是北京房价太丧心病狂了),靠给东北的朋友发些电脑散件以及后来零星翻译一些机械设备的英文技术文章维生,因为生性懒散不觉蹉跎至今。我要感谢那本莫名其妙的预言书"诸世纪",尽管我不是一个迷信的人,但是去年五一我看到那段著名的预言"1999年7月,恐怖的大王将从天而降、、、、、、"的时候还是有些犹豫,我认真地考虑自己可能即将结束的生命里有什么未了的心愿,结果发现只有减肥。从我有记忆以来我就是个痛苦的胖子,因为胖,我甚至不得不隐藏我性格里比较敏感忧郁的一面,因为胖子通常被大众潜意识里不由分说地认为应该嘻嘻哈哈,应该性情开朗,应该徐小平。他们对一个矫矫不群的胖子的性格能够容忍的上限是严肃,再出格一点就不行了,比如忧郁。虽然他们从来不能如此准确地说出这种想法,但是如果看到一个忧郁的胖子,他们就会直觉哪里不对了,他们的这种直觉的本质是,"你是个胖子,你凭什么忧郁呢?你还想怎么样?你已经是个胖子了。"所以很难见到一个肥胖的并且影响广泛的诗人,因为公众不能接受,任凭他的诗歌惨绿无比。当然胖子的痛苦永远不值得同情(除非是因为病理或基因导致),因为他们胖通常是因为缺乏坚强的意志(也许除了丘吉尔)。我就是个典型,我的肥胖完全是因为厌恶运动造成的,我有过十几次失败的减肥经历,我试过节食、锻炼、气功和几乎所有流行过的药物,包括在西方严禁非处方使用的芬弗拉明,我总怀疑我不如小时候开朗是因为误用芬弗拉明造成的,它减肥的药理竟然是通过使人情绪低落从而降低食欲,事实上,它根本就不是研制用来减肥的,它本是用来使轻度狂躁型精神病患者稳定情绪的药。我是中国落后的药检制度的严重受害者。 58 | 59 |   过了去年的五一节之后,我制定了严格的计划:每天只吃蔬菜、豆腐、全麦面包、鱼肉、橙汁、脱脂牛奶和善存,每天用一个小时跑10公里,也就是标准跑道的25圈。我不得不骄傲的是,我只用了58天就减掉了48斤体重,去掉休息的星期天,几乎是一天一斤。然后我心情平静地迎接了什么事情都没发生的7月。这件事过后我发现其实我还是很有毅力的一个人。但是我不知道我的毅力应该用来做什么,末日虽然没有来,但是新世纪来了,30岁也快来了,这真是一件让人坐立不安的事情。 60 | 61 |   后来我一度想移民加拿大,所以一边找资料看一边到天津大学夜间开办的口语学习班上课,一个班20多个人,一个外国教师(更多的时候是外国留学生)和我们天南地北地胡聊,除了政治。我一共上了四期这样的班,口语就差不多了,当然还是停留在比较普通的交流水平上,至少我看英文电影时还是需要看字幕,尽管在天津的四年间我看过大概600部英文电影。过了元旦,一个小朋友在和我吃饭的时候突然问我,为什么不去新东方教书,你应该很适合去新东方教书。我说我倒是喜欢讲课,但是一个民办教师有什么前途呢?他说如果年薪百万左右的工作不算前途那他就没什么可说的了。我得说我很吃惊。不管怎么样,我仔细地把我能找到的关于新东方的材料都看了一遍,我觉得这个工作很适合我,尤其是看到杨继老师在网页上说"做一个自由而又敬业的人是我的梦想,新东方是实现它的好地方"的时候。在我尽管懒散无为却又是勤于思考的三十来年里,好像还是第一次看到一个很适合我并且我也有兴趣去做的工作。杨继还转述席勒的话"忠于你年轻时的梦想"。我没看过席勒的东西,光知道有两个能写字儿的席勒,不知道是哪一个说的这话,但是我宁愿把它当成是新东方的精神。我听说教托福和教GRE薪水差不多,但是GRE的学习要苦得多。 62 | 63 |   我想了想还是选择了GRE,毕竟托福是专门给非英语国家的学生考的,教书的满足感上逊色很多。 64 | 65 |   旧历新年的时候,因为不确定是不是需要大学文凭才行,我试着写了一封应聘信给俞老师,提到我只有高中文凭,结果得到的答复是欢迎来面试,除了感激我还能说什么呢?我是说即便没有文凭不行我还是会来新东方做教师的,但是可能不得不伪造证件,作为一个比大多数人都更有原则、以知识分子自诩的人,如果可能,我还是希望不搞这些虚假的东西,俞校长的开明使得我不必去做大违我的本性和原则的事情,得以保持了人格的完整,这是我时常感念的。 66 | 67 | 过了春节处理了一些杂事,很快就到了6月份,我买了本"红宝书"就上山了。鹫峰山上的学习气氛和恶劣条件我都非常喜欢,应该是因为生活有了明确目标的关系吧。但是我很快发现,讲课教师的水平和他们的报酬以及新东方的声誉比起来还是很不理想的。我看到身边大多数的同学对所有的老师评价都很好,听到那些愚蠢的笑话、对ETS肤浅的分析导致的轻浮谩骂和充满种族歧视、宗教歧视的言论的时候,大多数人都笑得很开心。这最终再次有力地证实了我一直怀有的一个看法:任何一个相对优秀的群体里面都是笨蛋居多。无论台下是300名来听传销的社会闲散人员还是300名来听GRE的大学毕业生,对于一个讲课的人来说并没有多少区别,这也是他们在台上信口开河、吹牛放炮的信心来源。当然这里大多数同学专业都很出色都很勤奋刻苦,积极上进,性格上也远比我更具备成功的素质,我只是说他们缺少情趣,他们聪明(至少他们都敢考GRE的数学,这是我想都不敢想的),但是没有灵气,人品也未必差,只是缺乏独立思考能力。 68 | 69 |   我只喜欢陈圣元一个人的课,所以后来也就只去上他一个人的课,其他的时候一个人在宿舍背单词。陈圣元除了胡扯闲聊比较有水准之外,治学态度曾经也让我觉得很好,说起charter这个单词的时候,他说为了找到那个填空句子里面表达的意思查遍了所有的词典都找不到满意的解释,最后花了一千多块钱买了一本巨大沉重的韦氏词典(显然是指MerriamWebsters Third New International Dictionary Unabridged)才终于在该词典所列的关于charter的25条释义中的最后一条里找到了答案。说起市面上粗制滥造的填空参考书的时候他很不以为然,"我以三年的教学经验也精心编写了一本,那些作者对题目绝对没有我钻研得深,他们就会胡编乱造然后急忙出版抓紧骗钱,我这本可以说是这方面的集大成者,现在正在印刷当中,很快就可以和大家见面"。由于在山上的时候单词还没怎么背,题目都没做过,所以他这些态度和表现曾经让我很景仰。发现不对头是下山之后开始的,我录了他的全部课堂录音,我听着录音大量做题的时候,才发现他的分析讲解漏洞百出,尽管他批评过去的新东方老师都是拿了正确答案再进行分析讲解,可是他的工作显然也是一样,这样才能解释为什么他总是能用错误的分析推理给你一个正确的答案。另外我发现所有的三流词典,包括英汉词典,都在charter的第一个释义上就解释了他声称在韦氏第三版未删节新国际词典的25条释义的最后一条中找到的答案,"由君主或立法机关发给城市或大学,规定其特权及宗旨的特许状",所以我也买了本十多斤重的韦氏第三版回来,发现只有13条释义,而且在第2条里就解释了这个问题。现在他的那本填空教程就在我手边,仅在No、4的52道题中,我就找到了18处错误,如果说翻译的错误对学生不重要,那么解题分析的错误也有10处之多。这也最终使得我改了主意,决定做填空老师,本来我想做词汇老师,那样可以海阔天空地胡扯。 70 | 71 |   我以这样的条件敢来新东方应聘,除了脸皮厚这个最显而易见的表面原因之外,主要还是教填空课的自信。第二次考试之后我一直做填空的备课,最消耗时间的是把NO、4到1994年的全部填空题翻译成中文,400多个句子的翻译居然用了我整整一个月的时间,基本上是一个小时翻译三个句子,当然快的时候两分钟一个,慢的时候几个小时翻不好一句。翻译这些句子是我本来的备课计划之外的工作,最终使我不得不做这个工作的原因是钱坤强和陈圣元那两本"惨不忍睹"的教材。钱坤强的那本就不必说了,此人中文都有问题,尽管我坚信他的英文要远比我的水平高(也许应该说熟练),但是理论上一个人如果母语都掌握不好(这意味着他对语言本身不敏感),那么他肯定掌握不好任何其他语言,即便他能熟练运用,也不适合做语言方面的工作,比如文字翻译。他那本超级填空教程在新东方地下室卖了两年都没正式出版,一定程度上说明了这本书的水准。至于我非常喜欢的陈圣元,他在那本书的前言中说道:"翻译时尽量体现原文的结构,以便考生能对照原文体会原文句子结构的特征,从而体会结构与答案选项设计之间的关系......这样做会使得句子略显得欧化而不自然......不会去套用貌似华丽实则似是而非的成语。" 72 | 73 |   作为一个考试学习用的教材,他声称的翻译原则和宗旨是很好的,但是很遗憾,我看到的绝不仅仅是一个欧化或是不自然的问题。首先"体现原文结构"应该表现为翻译成中文之后原文中的各个句子成分最大限度地在译文中充当同样的成分,而不是把所有的成分不变动位置地翻译成对应的中文单词,这样的做法和那些《金山快译》之类的拙劣软件的翻译结果有什么区别呢?实际上《金山快译》这一类翻译软件的译文虽然狗屁不通,但是我们即使看不到原文,通过猜测也能大致明白它想说些什么,这就如同没学过日文的中国人看日文电器说明书里面夹杂的汉字也能隐约猜出大意一样。陈圣元的译文本质上就是这样的一种东西,当然程度上有些区别。 74 | 75 |   其实欧化并不可怕,尤其是在一本学习用的教材中,即使是在文学中,一些恶性的欧化今天也成了现代白话文的组成部分。陈圣元的译文根本不是欧化的问题,他的译文和钱坤强的一样,最恐怖也让人难以置信的是,作为所谓的译文,如果脱离了原文的对照,没有一个中国人知道这些句子在说什么,我是说这些句子字面上在说什么都没人看得懂,而不是因为句意晦涩难解而使人看不懂它想表达的内涵。 76 | 77 |   另外,看得懂的很多句子又翻错了,即便看不懂句子的意思真的不影响正确答案的选择,但是作为一本教学参考书,如果参考译文都翻错了,还怎么让学生信服呢?除非是以一种变态的方式,比如"陈老师的译文都翻错了,可是他的GRE考分那么高,可见看不懂句子对答题反而有帮助"这一种。 78 | 79 |   我的译文体现了这样几个原则,首先由于不是文学翻译,我注意了最大限度地使用原文的结构,使译文中的句子成分尽量充当原文中的对应成分。为了这种对应,有时候会有些比较不符合中文习惯的句子结构,比如一些在英文中可以置后的定语从句按照中文的语法放到了修饰对象的前面之后,句子显得臃肿不堪,另外还可能导致断句困难。针对这样的问题,我在这类句子中大量地使用了括号和破折号,很多时候,如果只读括号外边的内容,读到的就是这个句子完整的主干,那些使句子结构变得复杂的修饰成分都在括号里边,但是如果假定这些括号不存在把它们连起来读,也是一个通顺完整毫无语病的句子,这样和原文对照阅读时对应的成分和原句的主干结构清晰可辨。 80 | 81 |   在解题思路上我修正了陈圣元的书中所有不严谨的地方,难以置信的是这些不严谨的错误在他的书中竟有三成之多。我的草稿还有很多优点,虽然这些优点是我完成的,但是我不想为了向别人解释"我做的工作牛就牛在、、、、、、"这样的东西浪费太多的时间,所以不再分析了。如果我们都接受"不存在完美的东西"这样一个假设,那么我想说的是,我的这本填空教材是离完美最近的那一个。希望我的坦率不会倒了您的胃口,当然我知道新东方的开明气度才会这样讲话。 82 | 83 |   如果新东方出版参考书的惟一标准是书的质量,而不权衡其他方面的因素,那么陈圣元的那本书的寿命不会也不应该超过一年。需要做一个效果未必理想的声明是,我并非有意攻击陈圣元,他在课上说起,新东方的同仁们的一个优点是互相不会拆台,也许私下并无深交但是不会互相诋毁,这对事业或是人生的成功起到了相对积极的作用。这种观点虽然不合我的本性,但是我也知道如果大家都是书生意气,新东方也没有今天。所以我接受了他的这个看法,基于这一点,我也不想对他做更多的攻击,很大程度上我对他的看法现在都坦率地说了出来是因为他已经离开了,不存在和睦相处的问题。何况,他出色的幽默感和极佳的亲和力都是我很佩服的,毕竟他是新东方我见过的最喜欢的老师(如果不是惟一喜欢的)。对于他的工作和治学态度,我更多的是感到遗憾。 84 | 85 |   当然我知道会有一些年轻教师不屑地说,教教GRE,算个屁自学?那好吧。 86 | 87 |   我想我多半看起来像是个怪物,高中毕业,不敢考数学,居然要来做教师。但是我到新东方应聘不是来做教师的,我是来做优秀教师的,所以不适合以常理判断。即使新东方的声誉和报酬使得它从来都不缺教师,我也知道优秀的教师永远都是不嫌多的,如果新东方从来都不缺优秀教师,那么我也知道更优秀的教师从来都是新东方迫切需要的。 88 | 89 |   龚自珍劝天公"不拘一格降人才",如果"不拘一格"的结果是降下了各方面发展严重失衡的,虽然远不是全面但又是十分优秀的畸形人才,谁来劝新东方"不拘一格用人才"呢?想想王强老师的经历,所以我也来试试说服您,我们都知道那个美国老头虽然觉得他很荒唐,但是他还是给了王强老师一个机会去见他,一个机会去说服他,所以我想我需要的也就是这么个机会而已。给我个机会去面试或是试讲吧,我会是新东方最好的老师,最差的情况下也会是"之一"。 --------------------------------------------------------------------------------