我学习Android的一些套路

e1582zr2 6年前
   <p>今天我将给大家分享一下我学习Android的一些方法和想法,分享中并不局限于Android哪一块怎么学习。而是一个总体的,普适性的学习套路和方法。希望可以帮助大家解决一些问题。</p>    <p>注意本文为知乎Live底稿,知识点相对分散,后面部分包含了一些听众提出的问题,但是不影响总体的阅读和理解。</p>    <h2>Android需要打好哪些编程基础</h2>    <ul>     <li>Java基础(Kotlin)(参考技能树 <a href="https://simg.open-open.com/show/84adf383af2981c963239e1c1ad27249.png" rel="nofollow,noindex">http://olabqc6d8.bkt.clouddn.com/Java_skill_tree.png</a> )</li>     <li>OOP思想与设计模式</li>     <li>Android基础(参考Android技能树 <a href="/misc/goto?guid=4959755062635195646" rel="nofollow,noindex">http://7jpolu.com1.z0.glb.clouddn.com/Android_skill_tree.png</a> )</li>     <li>数据结构与算法</li>     <li>其他,比如JVM相关</li>    </ul>    <h2>除了编程基础,我们还需要补充哪些能力</h2>    <ul>     <li>喜欢钻研的兴趣</li>     <li>良好的英语理解能力</li>     <li>善于思考和总结的习惯</li>     <li>高效率的学习方法</li>     <li>能够机智地利用Google搜索</li>     <li>善于利用工具</li>     <li>和现实事物关联类比的能力</li>     <li>对待问题的态度</li>    </ul>    <p>1.喜欢钻研的兴趣,尽管高级编程语言的出现让我们将精力更多的放到业务上,而不是编程细节。正所谓知其然知其所以然,钻研细节可以更好地帮助我们实现业务,做到了然于胸。</p>    <p>2.良好的英文理解能力。由于一些原因,我们接触到的一些技术的资料都是二手资料,而这些二手资料往往在知识传递的效果上有一些折扣,甚至是偏差。英语可以说是(安卓)编程提升的加速器。同时,英语好的话,可以辅助我们写出更具有自解释的代码。</p>    <p>3.善于思考和总结的习惯。真理越辩越明,同样技术越思考越清晰。对于一个技术通常我们需要抱有这样的疑问</p>    <ul>     <li>它是什么 一句话概括</li>     <li>解决了什么问题 存在的意义</li>     <li>怎样解决了问题 内部的实现</li>     <li>它的缺点是什么 多角度分析</li>    </ul>    <p>比如我们关于WebView的考虑点的总结</p>    <ul>     <li>是否支持js</li>     <li>是否支持mixed content (https网页加载http图片)</li>     <li>与js通信的问题,比如给方法增加JavaScriptInterface注解</li>     <li>是否自身处理某些URL(协议不同,不让flipboard://showSection等)还是交给外部程序</li>     <li>关于UA中是否加入特定的标识,比如Flipboard字样</li>     <li>是否增加特定的header</li>    </ul>    <p>有了思考,我们需要以文字的形式记录下来,这也应了那句老话,好记性不如烂笔头。建议以博客的形式总结出来。</p>    <p>4.高效率的学习方法。</p>    <ul>     <li>理清楚概念很重要</li>     <li>做好控制变量法</li>     <li>多动手实践,与理论结合</li>     <li>抓住重点,剔除干扰因素</li>    </ul>    <p>其实,任何复杂的事情都是由简单的事情组成,编程也是一样。在编程过程中,我们会接触到很多概念,这些概念很重要,对于概念的一知半解往往会使得我们越走越慢,学习起来原来越困难。因此对于编程中的概念要务必理解准确和深刻。</p>    <p>控制变量法:我们在初中做实验的时候,经常会用到控制变量法。在编程中红也是。当我们在解决问题时,也要做到控制一处修改。比如我们项目中需要修一个webview相关的bug,我们要想一想能不能脱离现在庞大而负责的项目,单独写一个简单的变量单一的sample来重现,做到快速和小粒度验证。</p>    <p>多动手实践与理论结合:很多时候,我们学习新技术的时候,我们应该先学会使用它,有了初步的认知之后,便于我们更好的理解和深入研究。比如关于GUI的东西,我们最好时不时做出一些东西,理论和实践要做到相辅相成。</p>    <p>抓住重点,剔除干扰因素:</p>    <ul>     <li>任何复杂的事情都是简单问题错综复杂交织在一起,进行拆分</li>     <li>去除无关因素或者干扰因素</li>     <li>补充了解问题必备的知识</li>     <li>具象分析:看它的实现原理和运行机制 (比如通过分析源码,我们知道HandlerThread无非就是一个自带并初始化好了Handler的线程)</li>     <li>抽象总结:从适度抽象的角度进行归纳</li>    </ul>    <p>5.机智地使用Google。从事编程工作,使用Google是一种必须。虽然国内访问不了,但是对于聪明的程序员来说这不算问题。通常情况下,我都是讲想要搜索的知识点转成英文的形式,不包含中文。优先查看stackoverflow 和 google groups的内容。相比而言,中文的相关资源并不是很可靠,质量也普遍差一些。</p>    <p>6.善用工具,多使用终端,多尝试写一些脚本解决重复的工作。Python,Ruby,Shell脚本都可以帮助你写出很多利器。</p>    <ul>     <li>比如全文查找关键字工具 grep -E $1 --exclude-dir={.git,lib,.gradle,.idea,build,captures} --exclude={*.png,*.jpg,*.jar} . -R --color=always -n 能找出Android工程下面的包含某个关键字的文件以及所在的行数。</li>     <li>快速获取当前Activity的名称 adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' --color=always</li>     <li>快速检查json文件是否合法</li>     <li><a href="/misc/goto?guid=4959755062749312386" rel="nofollow,noindex">https://github.com/androidyue/DroidScripts</a></li>    </ul>    <p>7.和现实事物关联类比的能力</p>    <p>随着编程时间的增长,我们会原来越发现程序里的很多概念和现实生活中的事物是类似的。</p>    <ul>     <li>比如数据库的索引和现实生活中我们使用的字典索引。好处都是便于快速查找。不好的地方,索引多了会增加占用,增加,删除,修改同时连带索引修改会慢一些等。</li>     <li>比如对象池和现实中餐厅的公共餐具是类似的。我们都需要回收的时候,清理脏数据,避免影响到下一次使用。</li>     <li>比如KFC里面的餐具回收人员关于何时回收餐盘,和JVM的GC其实是类似的。一个对象不被其他对象持有,就可以回收。即一个桌子上没有人,只有餐具通常是可以回收的。</li>    </ul>    <h3>如何做到关联和类比</h3>    <ul>     <li>了解编程中的具体概念,抓住问题的关键点和关键行为</li>     <li>选择现实中习以为常的事物和行为进行类比,不要选择模糊不清的。</li>     <li>提取共同点,检查是否match。</li>    </ul>    <p>8.对待问题的态度 对待问题的态度一定要积极。不能得过且过。比如对待不容易/不能复现的问题,及时手头没有可以复现的机器,也要通过模拟/使用云设备 等方式尝试重现。</p>    <p>对于目前在做的只有自己已知的问题,不要隐瞒,尽量暴露出来,这样便于自己和他人更好的发现解决。</p>    <h2>作为Android程序员,如何把握好技术的宽度和深度</h2>    <p>对于Android来说,有太多的诱惑,比如React Native,小程序,热更新,插件化。</p>    <p><img src="https://simg.open-open.com/show/88c8cd0ca22a25fd7d7bd2ae718c886b.jpg"></p>    <p>我理解的应该是先从宽度上拓展,然后在尽心深度研究。</p>    <h3>什么时候需要横向拓展</h3>    <ul>     <li>初学者</li>     <li>工作业务量繁多,比如浏览器开发(普通App开发技术,HTML+Javascript等技术)</li>     <li>自身兴趣</li>    </ul>    <h3>什么时候需要纵向深入</h3>    <ul>     <li>中级和高级开发</li>     <li>追求更深入的细节和思想</li>     <li>工作内容需要</li>    </ul>    <h3>横向发展有哪些</h3>    <ul>     <li>ReactNative等技术</li>     <li>简单的后台开发 Java/PHP/Python/Ruby</li>     <li>IOS等应用开发</li>     <li>总而言之就是会的多</li>    </ul>    <h3>纵向发展有哪些</h3>    <ul>     <li>系统源码</li>     <li>各种技术的实现机制</li>     <li>操作系统相关知识等</li>     <li>总而言之就是学得精,知其然深知其所以然。</li>    </ul>    <p>我个人比较倾向于多花点时间做深入研究,在这个过程中会慢慢形成一种透彻理解技术的能力,有了这种能力之后就能触类旁通,学习其他技术也会更加轻松。</p>    <p>另外,工作需要时影响你朝着哪个维度发展的重要因素。所以选择一个公司要谨慎。</p>    <ul>     <li>通常大公司,优秀的团队会有利于你进行纵向深入</li>     <li>小公司,创业公司更多的会影响你进行横向发展。</li>    </ul>    <h2>如何从日常的工作中获取最大的收益</h2>    <p>日常的工作中,我们都是在做公司的项目。我们想要做到最大化收益需要做到</p>    <ul>     <li>不要将自己的要求仅仅停留在功能实现(比如完成一个界面不代表你的收益做到最大,只是代表任务完成)</li>     <li>要理解你所使用的技术的原理和本质。不要停留在API使用,否则无法增强你的竞争力。比如我们对于加载Bitmap都会用到LRUCache,我们则需要至少理解LRUCache的原理,如果可以的话,了解它的内部实现机制。</li>     <li>项目中有好的地方,要去思考好在何处。思考这种技术的通用场景。</li>     <li>在项目中思考更好的解决方法。做好两种方案的优缺点对比。比如你听了《Android Performance Pattern》中关于ArrayMap的讲解,也考虑到HashMap的空间占用问题,不要急于去替换。要做到对比(既要了解HashMap也要了解ArrayMap)同时结合业务场景来选择最适用的。</li>     <li>如果在项目中遇到了问题,建议先解决,然后空余时间研究这个技术的原理和细节。后续的研究务必要做。</li>     <li>善于做总结,将自己的经验和教训写成博客分享给他人。</li>    </ul>    <p>日常的工作给我们提供了许许多多好的实践和不好的问题,是一块弥之珍贵的技术提升的源泉。</p>    <h2>Android那么多库,我该选择哪些,怎么学,学到什么程度</h2>    <p>库的存在是为了封装细节,简化调用者实现或者辅助我们更容易发现问题。比如ButterKnife利用注解简化了对于view的查找和类型转换等功能。</p>    <p>关于如何选择那些库</p>    <ul>     <li>确定这个库是否是必需的</li>     <li>这个库能否带来开发效率的提升,降低代码的维护成本</li>     <li>这个库的学习成本如何 比如rxjava其实学习成本会相对高一些。</li>     <li>这个库的质量如何,不要仅仅看star,更要看issue的处理情况</li>    </ul>    <p>Flipboard常用的库(部分)</p>    <ul>     <li>LeakCanary A memory leak detection library for Android and Java.</li>     <li>Stetho Stetho is a debug bridge for Android applications, enabling the powerful Chrome Developer Tools and much more.</li>     <li>ButterKnife Bind Android views and callbacks to fields and methods.</li>     <li>Baber A custom view styling library</li>     <li>GoldenGate An Android annotation processor for generating type safe javascript bindings</li>     <li>MaterialEditText EditText in Material Design</li>     <li>。。。</li>    </ul>    <p>关于库,首先我们需要掌握其使用方法,同样也需要理解其运行机制。</p>    <h2>对于初学者,大学生的建议有哪些</h2>    <ul>     <li>越来越多的关于互联网寒冬的消息传出</li>     <li>听见越来越多的人抱怨Android找工作越来越难,已经趋近饱和。</li>     <li>Android开发的红利期正在逐渐消逝,尤其是对于初级和中级开发人员</li>     <li>关于现在加入Android开发队伍,我并不反对。</li>     <li>仍然可以赶上红利期的有容器,机器学习和人工智能。</li>     <li>但是无论选择哪一种技术,即便是Android,请具备好的基础和较强的编程能力和足够的爱好。不要仅仅追求物质。</li>    </ul>    <h2>一直想学,却很难坚持下去</h2>    <ul>     <li>有意愿是很好的。</li>     <li>如果很难坚持下去,可能的原因有没有学进去,或者自制力比较差</li>     <li>关于没有学进去,可以参考上面提到的学习方法</li>     <li>如果是自制力的话,可以通过自我监督和他人监督的方式来改善。</li>    </ul>    <h2>不知道去哪里学安卓,可以边学边工作么</h2>    <ul>     <li>学习Android的途径有很多,可以是自学(视频网站,看书,博客)也可以选择培训(不推荐)</li>     <li>边学边工作通常是可以的,不过具体实施起来还要结合自身的情况,比如时间是否充裕,学习者的决心和自学能力。</li>    </ul>    <h2>春招做准备,数据结构和算法不懂怎么办</h2>    <p>无论是春招还是秋招,对基础知识的掌握程度都是很重要的衡量标准,毕竟毕业生的实战经验比较少一些。</p>    <p>数据结构和算法应该是必不可少的一部分。建议还是要多多做一些准备工作。</p>    <p>呈现出最好的状态来面试春招。</p>    <h2>自己有一个什么样的个人项目才有竞争力</h2>    <h3>如果这个项目是App</h3>    <ul>     <li>首先有足够的用户量,比如月活达到上万的数量级</li>     <li>界面和交互处理良好,符合Android UI/UE规范</li>     <li>运行流畅和稳定,不存在低级的错误(比如卡顿等问题)</li>     <li>App能明显解决用户的痛点</li>    </ul>    <h3>如果这个项目是一个开源项目</h3>    <ul>     <li>有足够的star(然而这个已经被玩坏了)</li>     <li>issue的处理情况</li>     <li>contributor的数量</li>     <li>设计的思想是否优秀</li>     <li>代码是否居然自解释性</li>     <li>学习成本和维护成本尽量少</li>    </ul>    <h2>我该如何选择网络中鱼龙混杂的学习资料 pass</h2>    <ul>     <li>使用Google和StackOverflow,Medium</li>     <li>如果是博客文章,在自己能力可以理解前提下,尽量选择英文</li>     <li>最简单判断一个文章的优劣可以先到文章的底部看评论(Good,Execellent,Awesome)以及Google+,非死book,推ter分享数量</li>     <li>尽量选择内容整洁(说明态度认真)的文章</li>    </ul>    <h2>学习效果差的问题 pass</h2>    <ul>     <li>长期看慕课和论坛,感觉效果很差</li>     <li>感觉通过视频学习,进步很大,但是即使学习完了,感觉还是菜鸟</li>     <li>视频也看了,书也读了,但是写起来还是很吃力,下一步如何熟练和进阶</li>    </ul>    <p>产生这些结果的原因:</p>    <ul>     <li>通常的视频网站传授给大家都往往是立竿见影的技能。</li>     <li>学习中缺乏思考,无法做到触类旁通。只知道照葫芦画瓢</li>     <li>基础薄弱,概念没有搞清。导致做上层的东西举步维艰。</li>     <li>没有比较良好的辅助工具或者无法找到优秀的辅助内容。</li>    </ul>    <h2>如何提高安卓程序员的核心竞争力,项目理解能力还是技术能力,哪个更重要</h2>    <ul>     <li>什么是核心竞争力。表现在学习技术的能力,对待问题的态度,解决问题的技术方案。别的行业其实也是这样的。</li>     <li>具体如何提高核心竞争力,我上面有提到,参考程序员需要具备其他那些能力。</li>     <li>这两个能力是相辅相成的,很难做出孰重孰轻的决断。</li>    </ul>    <h2>大龄Android程序员的烦恼</h2>    <p>经常收到一些安卓程序员的邮件,其中有很多问题是,做了Android很多年了,为以后的职业选择惆怅。比如互联网寒冬,华为清退34岁以上员工等等。</p>    <p>的确,由于Android相关的工程师需求不如之前那么好,加之年龄越大,拼劲可能不如刚刚毕业的年轻人。这种烦恼是可以理解的。</p>    <p>走出烦恼的一些方法</p>    <ul>     <li>不断学习,夯实基础,拓展技术面。为什么总是提到这个,因为其实存在很多程序员,逻辑思维不强,还不爱学习。不断学习对于程序员来说至关重要。</li>     <li>提高自己的竞争力,不要成为仅仅面向API编程的程序员。要勤于思考,追求更高。求其上者得其中,求其中者得其下。你必须和5年前,甚至是10年前的你有改变,不能仅仅是一项技能重复了5年,10年。</li>     <li>建立个人品牌:写博客,写书,开源项目,写独立App等。注意这其中任何一个都是一个长期坚持才能完成的事情。关于写博客,我在以前的知乎live讲过一些技巧和思路,地址为 <a href="/misc/goto?guid=4959732975369395407" rel="nofollow,noindex">https://www.zhihu.com/lives/796775894273363968</a></li>     <li>其实现代人的烦恼,不论是否是程序员,很多都是关于物质生活的恐惧。买车买房,家庭支出等等问题。以及对于自己的能力无法满足物质支出的恐惧和担心。在自己无法改变的情况下,适当调整心态。</li>     <li>尝试知识变现,但是需要不断积累,需要时间。不能一蹴而就。</li>     <li>关于舒适区,学习区和恐惧区的理论</li>    </ul>    <h3>理论</h3>    <p><img src="https://simg.open-open.com/show/d376000f0aee4123a957d4576e9ec568.jpg"></p>    <ul>     <li> <p>“舒适区”, 对于你来说是没有学习难度的知识或者习以为常的事务,自己可以处于舒适心理状态。</p> </li>     <li> <p>“学习区”,对自己来说有一定挑战,因而感到不适,但是不至于太难受。</p> </li>     <li> <p>“恐慌区”,超出自己能力范围太多的事务或知识,心理感觉会严重不适,可能导致崩溃以致放弃学习。</p> </li>    </ul>    <p>对于一个人来说,最理想的状态是处于“学习区”,学习具有适当挑战性的东西, 一段时间后,“学习区”会慢慢变为“舒适区”, “舒适区”越变越大, 而一部分的“恐慌区” 也会相应变成“学习区”。</p>    <p> </p>    <p>来自:http://droidyue.com/blog/2017/10/22/to-way-to-learning-android/</p>    <p> </p>