聪明的程序员应该知道什么是最值得解决的问题
今天和大家说下一个男人和女人的故事
解决任何问题和解决正确的问题是有区别的。
男同事A是一个可以做任何事情的程序员。他可以创建与其他同行一样好的软件,然而,程序员之间的差异主要是有无经验,即使两者都具有相同的技术技能。
怎么可能?你不赞同这句话吗?
男同事A为一家商店建立了一个很棒的分布式在线预订系统。用户可以选择可预订的时间,即提供一种“可用时间”的查询。
女同事B是系统的运营商,使用男同事A写的代码。她负责接收线上预定的人并在店内提供服务。
但是,预订系统有问题,虽然系统状态会立即在服务器中更新,但用户必须刷新页面或重新输入网站才能查看可用时间的更新,这样会发生重复预订,如果有两个人同时查看“可用时间”屏幕,他们会同时创建相同时间的预订。如果在忙碌的一天发生这种情况,女同事B会在尝试解决商店中这种问题时遇到麻烦。这将使客户对服务不满意,并会让玛丽感到沮丧。
男同事A很聪明,想要解决它。他计划开发一个内存系统,立即更新“可用时间屏幕”并向浏览器发送推送消息,以便它可以实时更新UI。即使这还不够快,代码也会在完成预订之前检查以确认重复。如果用户在更新速度不够快时尝试创建重复预订,则系统会显示错误。
女同事B开始感到沮丧。男同事A花了太多时间来实现这个目标。
2个月后,彼得实现了改进。几天后,女同事B注意到没有重复预订了。
男同事A认为工作已经完成并继续下一步。
男同事A很聪明,他可以与其他人一样很好地解决任何事情!
两个月后,女同事B再次打电话给男同事A。预订系统运作良好。然而,几千名中的三个用户抱怨说,由于重复预订,他们在尝试预订时遇到了错误。男同事A认为预订系统在内存中的实时更新就足够了,显然不是。
由于围绕重复预订检查的复杂代码和验证,经过几个小时的调试和多天的分析,男同事A无法弄清楚发生了什么。他不知道如何重现这个问题,因为有太多可能的条件。该软件太复杂了!因此,他决定添加额外的日志记录,以便在再次发生错误时提供更多调试信息。
六周后,另一位用户设法创建了重复的预订并绕过了验证。
日志没有显示任何有用的东西,只有每个人都知道的东西:有限数量的人能够绕过验证并创建重复预订,并且无法重现问题。
男同事A相信他可以解决所有问题,但他没有。不同的是他只注意到太晚了。
十年后,我向男同事A询问了他在预订系统中对这一集的了解。
这是男同事A所说的:
我和我的同事Jasmin一起学习,分布式系统存在一些技术限制。诸如防止重复预订的限制是不可能在没有显着成本的情况下有效地解决的。涉及多台计算机,网络延迟等。当您大规模使用分布式预订系统时,您需要接受两个人尝试两次做同样的事情。如果没有发生这样的业务需求,例如没有重复预订,您需要将该限制纳入业务利益相关者并理解他们想要如何解决它。
例如,在操作员确认之前,服务器可能不会向用户发送通知。如果运营商具有用于通知重复预订的UI,则他们可以与两个用户通话并重新安排其中一个用户。这种情况发生在他们来到商店前几小时甚至几天。
一旦重新安排的成本变得太大,您就可以自动化该过程。
例如,您可以创建一个查看数据库的系统,并列出所有重复的预订。然后,您编写代码以向能够手动解决该复制的相关方发送通知,甚至可能是另一个部门。
如果手动解决复制的成本太大,那么您可以创建一个系统,自动向用户发送短信或电子邮件,说“抱歉,我们无法在上午10点为您服务,请再次预订”。您将相当大的成本从操作员切换到用户的一小部分不便。
如果用户的成本是不可接受的,那么您可以探索更复杂的验证方法。
这样,在每一步,您都会花时间编写能够解决正确问题的软件。你不要浪费时间试图解决不存在的问题。
男同事A了解到,将一些技术限制提升到业务场景并逐步发展而不是一次性解决所有问题更有价值。
多台计算机之间的连接就像宇宙中的通信一样。它是凌乱,复杂和异步的,事件以您最不期望的方式发生。它不像完美和同步操作那样工作,每个事件都是一个接一个地发生。
在尝试解决每个问题之前,请关注重要的问题。如果需求需要付出太多努力,请将其作为有效的业务场景处理。一旦你有足够的证据证明值得投入时间和精力来解决它们,那么你将有一个很好的问题需要解决。
男同事A认为他当时很聪明,但他花了很多年的经验才明白......
一个聪明的程序员不是解决所有问题的人,而是了解值得解决的问题的人。
很自然地认为这是“产品经理”的工作,但这是你的工作。下次遇到业务问题时,请查看边缘情况,看看是否可以将这些问题转化为有效的业务场景。
这是一个算法访谈和角色分离是规范的行业。我们需要的是程序员,他们能够理解他们带来的价值,看看权衡,而不是天真地假装他们可以解决所有问题。