“使用Retrofit对我们来说毫无意义”:关于Sberbank Online的Android开发



Google Play上有多少俄语应用程序说“安装量超过50,000,000”? 显然,每个这样的案例都是一个独特的故事,具有其自身的特点,因此与开发人员进行交谈将很有趣。 并且,当此类应用程序的评级也为4.6时,这会增强人们的兴趣。

Vladimir TebloevSberbank Online Android应用程序的开发人员之一。 春天,当Sberbank Technologies参加我们的Mobius会议时,他在那里做了报告,现在我们决定向Vladimir询问他的工作特点。


-首先,告诉我们您到底在做什么?

-在Sberbank Online应用程序中,我参与了Dialogs服务,该服务使用户可以一键转账并以全视图查看整个转账历史。 该服务可供该应用程序的所有用户使用-现在有3,700万人。

自2016年夏天以来,我一直在SberTech工作-那时,作为应用程序的一部分,仍然没有将团队划分为多个单独的团队。 后来,作为向敏捷过渡的一部分,他们开始将不同的团队分配给单独的应用程序模块时,第一个团队是Dialogs团队,从那时起我就加入了其中。

-每个人都有与Sberbank Online相关的“ Sberbank”和“移动开发”两个词。 但是在这么大的公司中,是否可能还会进行内部移动开发? 与外界有什么不同吗?

-是的,也有内部使用的应用程序。 我与它们无关,但是我知道React Native在这里被积极使用。 内部开发有其自己的要求:没有严格的设计审查和复杂的动画;使用跨平台解决方案可以更快地进行开发。

随着专业知识的增长,可以将其应用到“战斗”应用程序中。 尽管事实上Sberbank Online将能够积极使用跨平台开发,但我对此表示怀疑。 有许多困难,当您拥有数以千万计的用户时,即使是一个罕见的问题也可能会伤害到很多人。

-这个“即使是罕见的问题也伤害了很多人”对工作有何影响? 您是否必须应对一些较小的应用程序可能无法通过的奇特问题?

-有时某些“特殊”设备存在问题。 在一个自定义但广泛使用的固件上,它很难工作,我们不得不花很长时间才能弄清楚。 事实证明,问题出在设备本身的主板驱动程序中-尽管该项目仅适用于ARMv7,但他试图在ARMv5下模拟库。

当用户很多并且错误的代价很高时,这就导致了一个事实,那就是需要“一点一点”地推出所有内容,并认真遵循报告。 如果出现问题,我们将立即停止滚动并进行修复。 除了“按给定百分比的用户”滚动外,我们还在地理位置上部分扩展所有内容:Sberbank具有“领土银行”的概念,功能可以按区域逐步扩展。



-虽然一些时髦的创业公司可以高举MinSdkVersion并说“其他人都不是我们的听众”,但情况却有所不同,您不能向别人招手。 您当前的MinSdkVersion值是多少?

-现在是16岁,我们从去年的14岁开始将其从字面上提升。我们查看使用特定SDK的客户数量,如果版本低于5%,我们可以提高版本。 到目前为止,我们有许多使用Android 4.4 KitKat的用户,大约16%-我们需要支持他们。

-您现在是否正在考虑使用任何新版本,并认为:“一旦增加MinSdkVersion,我们是否会立即使用它?”

-当然,我想将最低API提升至Android 5.0,以便充分利用过渡动画等创新技术,该技术将在任何地方都可以正常使用。 但是,原则上,这不适用于编写功能,业务逻辑,因此这不是至关重要的。 通常,动画是由我们的设计师设计的,也就是说,可以手动实现。 因此,这个问题并不重要,它关系到开发人员的舒适感,“安心”。

在某些情况下,我们会检查版本,例如SSL固定。 在不同版本的Android中,它的工作方式有所不同,因此我们为“最高4.4”和“最低4.4”的Android设备实现了两个版本的代码。

当然,我想“只是为Android P进行开发,什么都不要考虑”-但这总是事实,没有任何进展。

-到提到的SSL固定。 显然,安全问题对银行非常重要。 这对您有何影响,您的工作与处理非银行应用程序有何不同?

-它对用户的个人数据采取非常严格的方法。 任何泄漏都是巨大的风险。 我们有一个安全部门,负责在每个版本之前测试我们的应用程序。 如果有意见,则将其处理权交给负责发现的漏洞功能的团队。

我认为,在小型公司中,通常没有安全部门会考虑该应用程序。 如果发现任何浅滩,它们可以在w3bsit3-dns.com或类似资源上弹出。

与安全性也有关的是,我们的应用程序使用了防病毒软件。 一些用户对该软件的存在不满意,但是防病毒软件的引入使我们的欺诈行为明显减少。 例如,在我们的SMS银行中,您可以在其中编写带有防病毒功能的SMS“向X卡的转账金额”,这方面的欺诈水平已降至最低。

-出于安全原因,如果智能手机扎根,银行会限制其功能。 Sberbank Online禁止针对有根设备使用什么?

-6月,我们放弃了具有root权限的设备所有者的有限功能。 现在,Android上的Sberbank Online的所有用户都具有完整的功能。 同时,借助欺诈监控系统,保护水平保持不变。

-为了安全起见,有必要限制某些东西,而不是用户,而是限制他们自己作为开发人员,拒绝他们以其他方式使用它?

-2015年,当我们想引入Retrofit时,他遇到了混淆问题,他在使用标准混淆器时做得很弯曲。 我们的安全部门指出了此漏洞,因为API的存在使银行充满了对网络的网络攻击以及破坏代码的风险。 然后,我们放弃了Retrofit,仍然不使用它。 据我所知,现在标准混淆器的问题已经解决。 但是我们已经编写了自己的HTTP客户端,它可以工作并且满足所有人的需要,已经为使用不同服务器的不同团队为此编写了许多包装器。 将其更改为翻新没有任何意义。



-不可避免的问题:您对Kotlin有什么看法?

-我们正朝他的方向走,但是很悠闲。 困难在于,许多不同级别的Android开发人员都在马上开发该应用程序,有人完全了解Kotlin,有人则不然。 总的来说,在实现方面没有不可克服的障碍,但是现在我们缺少观看Kotlin代码的审阅者。 如果我们明天都开始在科特林突然写作,那么人们将根据要求“撕毁”。 另外,就Kotlin而言,我们的管道中使用的静态代码分析器存在问题。

因此,Kotlin的实现步骤很短:例如,我们在Kotlin上编写测试并使用数据类(这样可以节省时间,从而避免为getter,setter,equals(),hashCode()等编写测试)。

现在它正在缓慢运行,在下一步中,我们要编写DSL以在Kotlin上进行测试。 同时,我们希望提高公司的Kotlin知识水平:例如,借助mitaps。

-就“对话”而言,您从事消息传递,但不直接与WhatsApp类似。 有趣的是:其他人的解决方案对您有多大用处?您在代码中使用了开源Messenger吗?

-当我们想添加表情符号时,此功能很有用。 我们遇到了一个问题,即如何用它们制作面板,在开放源代码中,我们看到了一个选项,可以通过键盘上方的弹出窗口轻松解决所有问题。 然后,所有东西都在高度上汇合,对用户来说无缝地呈现。

但是总的来说,审视别人的决定并不总是一件好事,而考虑到他人的经验,形成自己的决定会更有效率。 例如,最好不要完全看一下Telegram,因为由于Android应用程序源代码中的类非常庞大,所以弄清楚它并不容易。 我们正在尝试走自己的路,特别是因为与服务器的交互可能不同:在同一报文中,它是MTProto,我们有通常的WebSocket。

-我是一个懒惰的面试官,所以我决定只列出您在工作中与工作有关的事项,并询问每个项目“告诉我们确切的情况”。

第一点:您处于“应用程序模块体系结构”中。 我们已经说过将应用程序分为模块这一事实-关于架构,您还能说什么?

-与我们一起迭代开发,正在进行版本控制,现在我们已经达到第17版。

16日,引入了Clean Architecture。 我们同意由谁负责什么内容(表示,域,数据层),使用哪些实体以及在哪里使用,以及转换器应该在哪里使用-总的来说,他们绘制并解决了所有体系结构问题。

实现如下:所有新功能都必须写在我们的新体系结构上。 如果在拉取请求中某些东西偏离了设定的规范,则这种拉取请求将进行修订。 但是与此同时,他们并没有立即着手浏览所有旧功能,因为这可能会引起很多问题。

对于表示层,我们选择了MVP标准,但是我们的一些团队使用MVVM。 在表示层中,我们不受任何限制。 例如,我们看到了关于MVI的聊天,更确切地说,是关于我们有趣的MVI实现的聊天,这与开发人员Mosby编写的内容根本不同。

然后,我们切换到该体系结构的版本17,并实现了RxJava,这需要对体系结构进行更改。 如果我们使用严格的定义,那么现在我们的体系结构已变成六边形,从Clean开始,我们已经“分叉”了。 但是它们的相似之处在于两者都按照SOLID原理工作,因此一个人可以很顺利地流入另一个人。 现在我们正在努力。

在该体系结构的未来版本中,我们希望放弃用于实现MVP的Moxy框架,因为它会带来一些困难。 该项目很大,它使用注释处理,并且在对“较低级别”的模块进行更改时,构建时间会很大。 我们努力使开发人员的生活更轻松。

-第二点是“工作和内存消耗的优化”。 这个问题有多严重,对于使用旧设备的用户,我是否必须不断考虑它?

-这个问题是平台团队关注的重点,他们正在开发功能团队使用的工具。 相反,由于需要一支团队,因此需要这样做。 例如,在Dialogs团队中,在开发的早期阶段,聊天非常缓慢。 然后,我不得不卷起袖子,从探查器开始,查看应用程序中的瓶颈在哪里,弄清楚它们发生的原因。

例如,在优化方面,我们放弃了PNG,并逐渐将其从项目中清除,以便仅使用矢量。 计划今年在Dagger中优化依赖关系图,以加快应用程序的冷启动。

-让我们继续测试问题:您的情况如何?

-我只能谈论我们的团队,在其他情况下,此过程可能会有所不同。

我们的团队最初只有一名测试人员。 随后,他对只是测试感到无聊。 他开始要求我们帮助编写单元测试。 我们向他展示了如何为数据库编写测试,本质上是为了进行解析-并且他以这种方式卸载了我们,从我们那里删除了部分工作。 很好:他和我们都有兴趣。

随着时间的流逝,我们得出的结论是,我们需要自动化回归,我们需要编写UI测试。 最初,我和我的合伙人从事UI测试,后来质量部门加入了我们-我们的测试人员过去对后端进行了测试。 他们知道Java,现在将它们连接到我们的项目以自动化整个回归。 我们坐下来考虑了以下解决方案:Appium,Espresso,Selenium。

我们在Espresso停留,并开始共同开发方法。 为了方便测试,我们开发了自己的框架,例如Kakao。 我们于2017年初开始这项工作,现在我们有了一个大型框架,并且大多数测试都作为构造函数进行了组装,因为针对各种情况编写了许多对决和动作游戏。

现在,我们的测试人员正在积极地要求我们教他们如何编写UI测试,因为编写一次测试要比“刺穿”五台设备上的相同操作容易。 但是,当然,您并不能自动完成所有操作,某些情况下仍需要手动检查。

至于开发人员,我们的团队每两周举行一次回顾展。 在其中之一,我们得出的结论是,开发人员在编写功能后应至少进行alpha测试。 为了不弄清楚“应用程序在启动时崩溃”形式的所有基本错误。 因此,开发人员也连接到测试。 当我们准备一个主要版本时,我们需要快速测试该功能,每个人都坐下来进行回归并通过回归测试。 当检测到错误时,开发人员将与回归断开连接,迅速进行修复,然后再次进行。



-下一项:代码审查。 您是否有任何细节或“像其他所有人一样”?

-由开发人员数量引起的特殊性。 当公司中有十个移动开发人员时,两到三个人可以审查所有内容。 以及如何修改数百人的密码? 我们制定了“审查矩阵”。 我们选择了20到30个人,我们可以肯定他们可以很好地进行宣传,留下反馈并解决评论中有争议的观点。 他们带走了这些人,并将所有团队划分为他们。

为什么是矩阵? 这是为了确保所有审阅者具有相同的负载。 审查进展如何? 我们的团队至少需要进行三个评估。 首先是团队中的某人。 第二个-来自外部的人,来自不处理此功能的团队。 第三点-来自相邻团队的某人。 在我们的例子中,有几个相关的命令,它们都在查看我们的代码。 好吧,因此,应该收集所有构建:单元测试和UI测试应该顺利通过。 因此,我们进行了代码审查。

-接下来的一点是重构旧代码。 它是如何系统地发生的:恰好是按计划执行的任务,还是“您是否需要对旧代码进行更改-同时重构它”?

-总的来说,我们有一个特殊的“侦查原则”:如果您碰了一些老东西-善于做正确的事,那么您现在是合著者。 但是也有计划的重构。 例如,对于对话框,需要两个方向的重构:我们使用的通讯录和翻译。 取出通讯录,清洗,然后在Room中重写整个数据库,并在单独的模块中执行。 如果您还记得这一点,我们的付款是很久以前使用RoboSpice编写的,这对我们造成了伤害。 我必须说,消除这一点是一项不愉快的任务,因为与此有很多联系。 而且您必须巧妙地对其进行清洁,以免破坏其余功能。

-即使在Sbertekh,您也参与培训程序员。 公司内部的培训是什么样的?

-自9月起,计划进行内部员工再培训等计划。 现在,我们已经定义了有关Java和Android的一系列主题。 例如,我们有想要在Android上进行再培训的javascriptor,javists和分析人员。 将为他们组织这样的学校,并根据时间表和讲座进行重点学习。

现在,我们定期举行mitaps。 为他们选择主题的方法与在会议上有所不同,在会议上需要新颖和大肆宣传。 例如,如果我们知道开发人员在某些方面有问题,那么谈论这一点很重要。 最近,我们的一位开发人员谈到了矢量图形。 不仅是关于在Android上精美绘制矢量的特定库,而且还从矢量图形的总体工作开始,然后到私有的。 他们讨论了Room和许多开发人员遇到的Java并发问题,以及Dagger 2。

去年,我们有一所Android开发学校,并聘请了成功完成该课程的人。 这样的人不应该立即与某些项目联系起来,只能自己做饭。 因此,每位新来的员工以及初级员工都将得到一个指导者,后者将指导他,发展和帮助他。 这是内部学习。

-面试:您是否“像其他所有人一样”接受采访,还是有特殊性?

-我曾经以为“和其他人一样”,但最后证明他们仍然有些特殊。 根据我的经验,市场上有三种常见的方法。 第一个被问到三个或四个主题,并仅对它们进行评估。 例如,我以Android开发人员的身份来到公司,被认为是必须具备Java的算法和同步方面的出色知识,同时又不欣赏我在超级库中所做的事情的人。这可能是由于公司需要一个完全需要了解框架或语言的狭窄部分的人。第二个-通过袖口进行采访时,几乎可以进行30-40分钟的对话。在这里,问题在于面试官的能力和经验。第三-在接受采访时,他们谈论公司的问题,并试图当场获得某种解决方案。这种方法的缺点是解决方案可能与提出此问题的人的观点不一致。我认为,在大约一半的案例中发现了这种方法。

对于我们来说,我们已经制定出一种方法来考虑四个方面的候选人:OOP,OOD(面向对象设计,架构),Java Core和Android SDK。我们逐个问题地讨论所有主题。如果候选人整体上对该主题充满信心地回答,我们将逐渐开始深入,提出更具体的问题。形象地,它看起来像一棵树:我们有一个根,从那里我们进入每个主题,并且可以深入五到七个步骤。然后根据所有通过的问题对候选人进行综合评估。如果面试很快,那么我们开始询问有关库的信息,例如Dagger 2,RxJava。如果有足够的时间这样做,那么根据科特林的说法。因此,对候选人进行整体评估。如果一个人不理解一个主题,但是对另一主题很了解,这并不意味着他是一个糟糕的程序员。这意味着他应在一段时间内加强该主题。

“您的另一项工作任务是“研究和审查新技术。”在这里,我想提出一个经过审查的技术的具体示例。

-最后一个主要的库是RxJava,我们研究了它如何影响我们的项目。我们在本地分支机构对其进行了测试,然后在一个非关键模块中对其进行了实施,以查看其在生产中的行为。毕竟,他们将其作为标准并决定每个人都在其上编写新功能。

在失败的示例中,我们考虑了Retrofit,我已经提到过:一个很好的库,可以解决其问题,但是对于我们的项目来说,它的时间已经过去了。实施它以使我们有多种进入网络的方法是不好的做法。

我们还考虑了用于实现状态机的TinyMachine库-该库很简单,不能扩展,也就是说,它满足一个命令,但不适合其他命令。因此,他们拒绝了它,因为即使您“拖动”该库,也只有适合所有人的那个库。结果,我们决定编写自己的状态机,所幸的是,这不是某种火箭科学,很难实现。

-最后:保留记录。在您的情况下,如果有很多开发人员,并且没有准确的文档,就不可能牢记所有内容,那无处不在吗?

-是的第一种文档是Java Dock。我们有一个本地模因“ Prilutsky的验证”:没有Java停靠站-拉取请求没有通过(“ Prilutsky”以Android开发团队中的一位领导者为荣:他经常在所有请求中写信,因此应加以描述代码的文档,如果没有此文档,代码将不会进入产生这种模因的常规分支。现在,开发人员已经知道,每个公共方法,每个类,每个构造函数-一切都应由Java文档描述。所有代码都应该停靠,甚至是测试。为了明确说明该测试的目的,例如,不会出现“这是什么费用?”的问题。是来自Messenger的付款还是来自付款的付款?什么是paymentTest?”

另外,我们在Confluence中有文档。当我来到这里时,在云端描述了我们的材料设计准则,并且有几篇关于我们工作方式的文章。现在,必须在Confluence中描述影响每个人的所有全局性事物。例如,我们需要插入证书来访问存储库,而这样做的人写了一篇文章,以便以后他们不会在聊天中写一百万次,以防证书损坏。另一个例子:决定实施RxJava,并且Confluence描述了最佳实践-如何做得好,如何不做以及到示例的链接。最简单的示例:如何在类中安排方法,以使所有内容都是标准的。

这些文章是逐渐但定期撰写的。现在,我们的Confluence涉及各种问题的文章已增加到200条。这样的工具也可以帮助新手。他们学习Confluence,了解内部开发厨房的概念,在遇到问题时,他们可以独立思考并做出决定,而不必总是让其导师参与。

Source: https://habr.com/ru/post/zh-CN422457/


All Articles