阿里妹攻略:Android和Java开发在技术栈上有什么区别?在思考和解决问题时会发生什么样的变化?本文分享了阿里技术达人从Android开发到Java应用开发的经验和感受,分析了两者的区别以及对动态、兼容性、内存管理和状态等问题的一些看法,总结了Android开发所需的技术栈以及阿里的Java开发。写在前面,记得刚毕业的时候,还是BBA争霸的时代,无线迎来了黄金时代,就像现在的“AI”和早些年的“云”一样,一切都需要依赖热点,基于PC的互联网企业纷纷发出allinwireless的战略口号,无线业务遍地开花,甚至企业的每条产品线都迫不及待想要一款app。到现在为止,他们都聚集在了旗舰上,但这是一个故事。2013年,在那个环境下,发生了几件事情:iPhone5s发布,Android升级到4.3版本,还有……我毕业了,哈哈。作为学校招收的新人,对长期的职业规划和技术栈的发展潜力了解不多。就像大多数程序员一样,希望跟随甚至推动行业的潮流,而不是熟悉某个版本的Android和某个API你必须先设置为false,否则你会以二手知识为荣喜欢华平,可惜,在种种取舍和抉择中,你最终锚定了百度上海校招的研发岗位,一下子集齐了我最讨厌的两个东西:Java和客户端!就这样,做了将近6年的Android客户端,经历了2.3和4.0的兼容地狱,从webkit到chromium的升级,从dvm到art的改造,热修复,各种动态部署狂潮,Androidstudio也从0.9Beta走到了今天的4.0,彻底淘汰了古老的Eclipse+ADT,有点感慨。直到去年,我终于有机会拥抱变化。得益于团队中的多个业务方向,我避免了工作调动,成功转战Java应用战场。快一年了,突然有一些想法,想和大家分享一下。除了Java本身,它其实是不一样的。从Android切换到客户端会更容易吗?团队中的其他同学也相继投入到Java应用的怀抱中,朝着“全栈”开发方向发展。.闲暇之余,我也会交流一些心得。比如IOS同学会觉得Android转Java开发有比较大的优势,从IOS转过来会格外困难。毕竟,OC或Swift和Java可能看起来完全不同。但是站在一个曾经的AndroidDev的角度,我在这方面的感受是:从我个人学习OC的经历来看,我觉得OC同学学习Java要比Java同学学习OC容易的多,Java更接近naturallanguage的表达,而且好歹在大学的时候大家都学过一点点~在没有Java语言本身优势的时候,Android和Java应用几乎没有半毛钱的关系,能做到的框架也少之又少可以直接使用。如果说有优势的话,只能说Androidstudio也是基于IntellijIdea,开发还算顺利。当然也不能说得太绝对,否则很容易上当受骗。毕竟Java本身就为那些框架能力提供了基础,而客户端也利用了DVM(如JVM)的JNI能力进行热修复、动态代理,甚至有的使用cglib、aspectJ来实现AOP的方案。但是在生产环境中,语言本身提供的能力是不够的。一种语言能否被广泛使用和接受,取决于生态、社区和大家贡献的库。这也是Java虽然可能不是最好的语言,但仍然是使用最广泛的语言的原因,除了语言之外,它们之间确实没有太多共同点。技术栈差异以阿里的生产环境为例。做一个Android开发或者Java开发的“攻城狮”,你大概需要的知识图谱如下(图谱是根据你自己的认知,有的并不详尽甚至是错误的。LocalWang指出):Android开发:Android技术栈知识图谱Java应用开发:Java技术栈知识图谱可以看出,从大类来看,都是相通的,无非就是基础框架,扩展库或者中间件,以及一系列的支持平台等不管在套路上用什么技术,发布和监控大概都是一样的,但是偏向有本质的区别。面向客户端的Android框架核心解决了事件交互、生命周期、视图绘制问题以及人机交互的逻辑问题,而Java服务器上常用的Spring框架核心更关注服务之间的耦合,依赖关系,以及面向大规模集群的扩展能力。基础框架不同,类库和中间件难免会有本质区别,几乎没有共性。这些设计思路带来的差异,必然要求开发人员在切换开发角色时改变思维方向。思考问题的角度发生了变化。看之前的代码,记得刚从C/C++学Java的时候,还是学生的时候,总喜欢一个main函数配一组静态方法实现主流程,后来学Python用For一些数据分析和脚本处理,总是着急没有地方声明变量类型,不习惯a={}等map声明方式。所以,转型中,不仅要入乡随俗,还要入乡随俗,最重要的不是换一些库和工具而已。动态动态曾经是客户最看重的能力。从hotfix到dynamicdexloader,再到RN、Weex、Dinamic中一系列动态能力的构建,可以说是面试必考题。无论你是Android菜鸟还是Android高手,让你说说你知道的动态技术方案,以及它们之间的区别。几大厂商热修复方案的对比是一个分享,每个AndroidDev都需要准备PPT,Android是这样,IOS也不例外,直到IOS禁止了动态加载的能力。对于客户端,发布周期与服务器端有很大不同。根据我们之前在手机淘宝的整合经验,安卓端覆盖80%的用户大概需要3-5天的时间。早些年比较慢,因为没有统一的Appstore静默升级,需要在各个应用市场更新或者推送更新。IOS会稍微好一点。自古就有应用市场,但毕竟一个更新周期还是远大于后台的周期。应用程序发布以分钟为单位记录,最多以小时为单位。这样的差异导致客户端的开发过程必须考虑:使用动态框架,从紧急修复到动态发布,一方面是应急,另一方面是加快版本迭代和收敛效率。那么,设计的业务框架和编写的组件是否具有动态修改和扩展的可能性,是否存在无法热修复的编译、混淆和优化风险,是设计和开发过程中需要考虑的点。不可逆释放。不仅因为是面向用户的,只要发出去的版本有问题,大概率是没有时间和机会修复的,很容易造成大舆论和失败,所以客户端的测试工作会比较吃力,全功能回归发布之前必须遵循的流程。但是这些问题在Java应用中并不明显。虽然有热部署框架,但只是为了部署效率,不会作为核心能力提供。兼容性也是因为迭代周期长,无法做到全面更新。客户端也会面临版本兼容的一大问题。目前安卓已经更新到11,但不排除4.x版本上市。同样,App已经发展到X版本,1-N版本也遍布市场。版本覆盖后的数据兼容性,尤其是sqlite升级,会让Android开发者苦恼不已,往往容易出现启动闪退的问题,迫使用户重新安装。服务器端很少出现同样的问题。唯一的可能就是协议的改变,但往往可以在短时间内共存和迁移。除了端上的数据兼容,另外一个兼容就是API和设备的兼容,尤其是2.x到4.x时代。同一个视图实现在不同的Android机器和不同的APILevel上可能会有不同的表现,修改方案往往会看不清对方。往往所有的主流车型修改一次就得退货。开发同学,差点有摔掉电话的冲动。当然,现在API日臻完善,compat包也解决了很多兼容性问题,开发体验有了质的飞跃。从这个角度来看,Java应用面临的问题就简单多了。是不是部署环境有问题?使用Docker虚拟化!这真是无穷无尽的乐趣!内存管理,但服务器端应用并不意味着更简单。说实话,去年我差点被onlineFullGC弄死。一大波流量袭来,持续的FullGC导致集群卡顿,大量服务超时引来客户投诉。重启和扩容解决不了问题,还得找到问题的根源来解决。FullGC是Java应用中的常见问题,但在客户端根本不需要关心。client分配给app的内存通常只有128M到256M,跟server端几G的内存管理不太一样,不会太在意GC,除非是极端的性能优化场景,更不用说使用G1仍然是CMS(当然,Android也不是)。通常只关心泄漏和OOM。OOM毕竟是客户端唯一的内存杀手,所以就有了一个大图片加载库来解决对象的内存管理问题。毕竟一个APP是不可能在你的手机里存活下来的。在时间上,前台的时间就更少了,不用考虑长期运行的累积问题。状态问题客户端的状态一般存储在页面本身。页面或视图作为一个对象,获取数据、渲染数据、呈现给用户,负责与用户交互、反馈和修改页面状态等一系列动作,并关闭其中几乎所有的行为状态一个页面,形成一个交互对象。强耦合。但是JavaBeans可能不这么认为。所有Bean原则上都是无状态的,数据存储在专门的db或center中。这也是分布式系统的基本要求。这是设计思维上最大的变化。客户端是否有并发问题?事实上,有。Android支持AsyncTask、HandlerThread,甚至更底层的Thread和Looper,但客户端的线程数通常是个位数或几十个。异步线程的模型也比较简单。通常,它只处理一些数据。毕竟UI刷新要在主线程完成(SurfaceView和TextureView除外)。主要逻辑在主线程的交互事件中处理,几乎没有难点问题。同步问题。但是,Java应用需要考虑的东西太多了,比如多线程同步、一致性、原子性、锁等。书上可能无法解释清楚。或许这也是Java应用程序令人着迷的地方。到最后写了这么多,我不善言辞,随便玩玩。想到什么说什么,更多的是对自己开发过程的一些感受。细说区别,还有太多的方向没有说到,知识图谱中的每个点都可以详细拿出来。但我想表达的无非就是在开发过程中,每一行代码,每一种设计模式的使用,思考的侧重点和角度都会有所不同。我们经常听到“全栈”这个词,但对我来说,你熟悉多少种语言和框架,并不是全栈的意思。可以尝试不同的技术栈,从不同的角度去思考和解决问题,并很好地掌握。是全栈给了我们最大的价值,这也是我个人所追求的技术“道”。
