一点评论:作为微软曾经的“铁粉”,如今是恨铁不成钢。这家公司已经老迈,早就丧掉了互联网时代引领浪潮之巅的能力。个人认为,他们操作系统产品的高峰是Windows XP和Windows 7。Windows 10刚出来的时候,我的机器天天蓝屏,几乎无一例外,成了小白鼠。以至于在群中成了笑谈。

好心的朋友帮我联系了微软的技术支持,提交了dump文件 – 实际上我自己也能分析,以前很喜欢这类debug,现在没兴趣了。微软反馈曰:是谷歌chrome浏览器的问题,是它导致的蓝屏,让我卸载,然后使用微软的浏览器。我差点没爆粗口,这就是你们解决问题的方式?如果我是老板,骂都骂死你们。

一个浏览器都能让OS蓝屏,这操作系统是什么质量?还好意思让用户卸载别人的软件,用自家的产品?这是开发人员的耻辱。Windows 10的bug堆积如山,输入法系统问题就很大,我2年前提交的bug,现在都没能修复。产品质量弄成今天这样,不是单方面原因,是值得认真总结教训的。还有,操作系统不是网站,操作系统出错,一切依附的软件都会瘫痪崩塌,我不觉得敏捷开发模式适合OS开发,出了问题影响太大了,又因为部署的原因,很难立即修复。


微软最近发布了 Windows 10 October 2018 Update,结果发布之后却立马曝出了严重的文件丢失问题,迫使其不得不暂停发行更新内容。目前,该问题已被修复且处于重新测试的阶段,等待再次发布。

显然,这已经不是微软第一次在Windows功能更新时出现问题了,以前就发生过更新中存在重大的硬件不兼容等问题,但这次肯定是最糟糕的一次。虽然我们大多数人都知道备份的重要性,但实际上大量数据(尤其是家用个人电脑上的数据)都没有真正备份过,这些数据的丢失后果简直是灾难性的。

 

Windows即服务

微软对Windows 10寄予的厚望导致其开发方式发生了彻底的改变。

为更好地响应客户和市场需求,并尽快将改进的新功能展现给客户,微软将Windows 10定位成Windows“最后”的一个版本,所有新的开发工作都将反映到Windows 10的更新中,并每年提供多次功能的更新——这个新的开发模型被称为“Windows即服务”。在经历了一些初步的摸索之后,微软决定每年进行两次功能更新,一次在4月,一次在10月。

这项努力并非没有成功。微软已经通过新模型提供了有用的新功能,所以用户不必再等三年的时间才能进行新的版本升级。例如:有一个巧妙的功能可以在虚拟机中无缝运行Edge,借以提供更好的保护,免受恶意网站的攻击;Linux版的Windows子系统(WSL)可以让Windows系统在本机运行Linux软件,对开发人员和管理员来说无疑是个福音;与SteamVR兼容的VR功能、对游戏性能的改善和暗色调主题都是很不错的附加功能……但这些更新对于纯粹的消费者来说好处可能不是很明显。但即使整体改进变小了,目前的Windows 10肯定还是比三年前发布的版本更好得多。

 

如果Windows依然三年一更新的话,可能还要很久才能开发出WSL工具

这是一件好事,我甚至认为,如果没有Windows即服务,那么部分功能可能就无法完成(或者至少不能成功地完成)。例如,WSL的开发受到了用户反馈的指导,WSL用户告诉微软他们发现的不兼容性,并帮助微软优先开发新的WSL功能。我不相信WSL如果不是每六个月更新一次的话它是无法获得现在这么大的影响力的——毕竟没有人愿意花三年时间来等待一个小修复,只是为了让他们的软件包能够正常运行……定期更新可以鼓励人们报告错误,因为他们可以亲眼看到这些错误得到及时的修复。

但是Windows即服务的问题出在了它的质量上。虽然没有明确的数据,但是很多主流的声音都认为Windows 10采用每月一次的安全更新以及每年两次的功能更新是一个疯狂之举。这样的抱怨一直都存在,在Windows 10发布后不久,其bug不断的更新内容就引起了广泛诟病。

最近的这次数据备份问题就又把微软的更新模式推向了风口浪尖,有评论说,每年两次功能更新太过于频繁,应该减少至一次,而且微软需要停止开发新功能,应该专注去修复它的各个bug。事实上,很多人都在担心微软的频繁更新会损害大家的信任,但其实一些用户可能已经完全丧失掉信任感了。

这也不是第一次有人呼吁微软放慢功能的更新速度了。他们担心IT和消费者领域的用户会因为这种“自杀性”的更新出现大面积的流失,随着这次更新出现的低级错误,这种呼吁显得尤为紧迫。

问题不在于更新频率,而在于更新方法

但是说微软每年只应该发布一次更新而不是两次、或者批评Windows即服务的想法,这类的看法其实没有抓住要领——微软的问题其实不在于发布频率的多少,而在于开发流程上就出现了问题。

为什么说这是个关于流程的问题,而不是时间线的问题呢?在发布计划方面,我们可以通过其他软件的做法了解可能出现的情况。

macOS、iOS和Android每年的更新不止两次,因此从某种意义上说,微软正在试图超过它们。跟微软有类似想法的厂商有很多:Ubuntu每年都会发布两个版本;Google的Chrome操作系统,比如Chrome浏览器,每六周就会收到一次更新;除了操作系统领域之外,微软的Office Insider计划也是每月一次更新为Office用户提供新功能,并且可以在没有太多投诉的情况下实现这一目标,同时提供稳定的新功能和修补;Visual Studio团队同样可以为其开发环境和在线服务提供频繁的更新……很显然,微软内部的部分团队已经很好地适应了定期更新应用程序的做法。

微软在努力超越本地软件的世界,进军在线和云服务领地,我们可以看到,无论是在内部还是在其他领域,微软都在朝着持续交付的方向前进。系统的每次更新在通过充分的自动化测试后,都会自动部署到产品服务器上。

的确,鲜有项目像Windows一样复杂。就比如Ubuntu,它可能包含有更多种类的软件包,但它的优势在于许多软件包都可以作为独立的单元开发。当然,Windows也确实包含许多单独的组件,但微软做了很多工作来解决这些问题。这也就导致了Windows的规模仍然异常庞大而且集成度异常高,而且在某些方面,Windows仍显得非常古老。

这些因素肯定会让开发Windows变得具有挑战性,但是难道这些挑战性是因为每年两次的发行导致的吗?——这一点尚不清楚,但是微软确实需要正确的开发流程。

Windows 10大约在2015年发布(我所有的图标在哪儿?哦,开始菜单?)

历史遗留的流程

微软尚未完全透露Windows 10的开发流程,但从看得见的流程(向Insider用户发送新功能的方式,以及Insider用户必须忍受各种bug)结合从公司内部收集到的信息来看,微软的流程确实存在着很大的缺陷——这与当年每三年发布一次Windows时的流程有许多重要的相似之处,虽然现在时间跨度大幅度压缩了,但是很多开发方法仍然没有改变。

过去,产品发布周期为两到三年的时候,微软的流程分为几个阶段:设计和规划、功能开发、集成和稳定。

  • 设计和规划大约需要4-6个月,集中编程需要6-8周,然后是4个月的集成(通常每个功能都在自己的分支中开发,因此必须将它们合并在一起)和稳定(也就是说:测试和bug修复)。
  • 在产品开发周期的过程中,各个阶段的循环将重复2-3次;Windows有3次迭代,第一次是原型,接下来的两次是真实的产品。阶段的长度可能会发生变化,但基本结构在公司内部广泛使用。

这个过程很显然存在一些问题。

也许最引人注目的是,实际开发新代码所花费的时间非常少:在整个三年一次的Windows发行期间只占到了6-8周的时间。相对实际在产品上工作的时间来说,规划和设计阶段占据了非常长的时间。

也正是因为这个原因,他们的流程不能称之为“敏捷”。当将功能摆到客户面前使用的时候,新功能已经融入了最终产品,因此很难根据反馈进行更改。

开发和改bug的分离也是一个问题:在开发和集成阶段,软件的可靠性和稳定性将会急剧下降。集成的功能根本未经测试(因为测试放在了后面的阶段),而且功能之间也未曾相互使用过(因为它们都是在集成阶段之前在各自的分支中单独开发的)。

然后,在冗长的稳定阶段通过测试,报告bug以及改bug,将混乱的软件打造成可以接受的状态。在这个过程中,产品的可靠性应该再次开始提高。

新世界并不那么新颖

在新世界里,我们看到微软的整个开发周期需要7-8个月的时间。虽然两次发行之间只间隔6个月,但在上一个周期结束之前下一周期就需要开始,所以每次“提前开始”的组重开,Insider用户就知道又要分散精力了。

  • 通常每次更新刚开始的时候都非常平静,几乎没有明显的变化,但是在接下来几个月里会发生重大的变化,同时引入大量bug。
  • 在更新发布之前的一个月里,我们会发现变更的数量会急剧减少,而且人人都会更加关注修复bug而不是新功能。

正如上述微软员工所描述的那样,开发最后的几个月分为一个“告诉”的阶段,然后是一个月的“请求”阶段。在“告诉”阶段,大家告诉Windows的领导正在进行的更改,而且他们只能默认接受所有的更改。在“请求”阶段,大家的状态自动切换成拒绝,在这个阶段只允许真正有必要的修改,通常每天只能做出尽可能少的几个改动。

因此,例如,10月更新的第一个版本(代号RS5)已于2月14日发布给Insider用户;而更新的稳定版本(RS4)直到两个月后的4月16日才发布。在3月7日之前RS5并没有收到任何重要的新功能,到了5月、6月和7月相继增加了许多功能,一直到8月和9月才截至,所以这两个月只有很小的修改。 8月份甚至删除了一些小功能,因为无法在10月发布时及时准备好。

当然,这个过程并不是每次都完全一样。例如,我们看到新功能在预览版本中出现了几个月。这表明随着功能的开发,新功能的集成似乎发生得非常快,而不是在最后进行一次大融合。

质量出现了大跳水

但是微软的开发过程也存在一些重要的相似之处。最重要的一点是众所周知的代码集成存在大量bug,以及在测试和稳定阶段就急于解决实际问题。他们甚至明确承认这一点:在宣布新版本的预览时,微软警告说“开发周期的早期版本中所包含的bug可能会让一些人很痛苦。如果这让你感到不适应,你可以需要考虑切换到慢速通道。慢速通道发布的版本将继续保证高质量。“

我们可以在RS5中看到过这方面的一个例子。去年10月的更新为OneDrive引入了一项新功能:占位符代表存储在OneDrive却没有下载到本地的文件。每当应用程序尝试打开文件时,OneDrive将直接从云存储中获取文件并将其保存在本地,而应用程序无需知道最初本地有没有该文件。如果磁盘空间不足,那么RS5可以让用户选择性地从本地存储中清除云复制文件。

这是一个非常聪明且很有用的功能,可以无缝使用云存储。而且该功能的代码是全新的,由一个内核驱动程序为云同步代码(用于下载文件和上传更改)与文件系统中的占位符提供了粘合剂。他们还提供了一个API(第三方可以将他们的代码连接到同一系统,就可以提供他们自己的同步服务)。

 

大家都以为微软会围绕这些新代码进行一系列测试,验证它是否正常工作:创建文件,检查是否正确同步,删除本地副本留下的占位符,打开文件获取真正的文件,完全删除文件,等等。这里面包含一些围绕文件和目录的基本操作,在任何完善的敏捷开发过程中,所有的这些操作都需要通过测试来验证其是否按预期工作,并确保API可以提供相应的服务。

另外,大家都认为凡是未能通过测试的变更都会被拒绝而不会被集成。这些代码应该做到完善,应该通过相应的测试,才能合并到Windows主要的代码中,更不能发送给beta测试者。

然而,事情并非如此!许多预览版本都有一个bug,删除同步到OneDrive的目录会导致机器崩溃。所以这个bug不仅集成到了Windows代码中,还发给了最终用户……

 

测试应该在发布前进行,而不是发布后

这件事情向我们揭示了Windows开发过程中的一些基础问题。这些代码根本没有通过任何测试(据我的了解这是真的,他们允许集成未经测试的代码,尽管我希望这不是常态),或者测试失败也是可以接受的,测试失败并不会阻碍其他工作,而且允许开发人员集成已知无法正常工作的代码。虽然我们作为外人无法确切地知道具体情况,也许这两种情况都有,但无论哪一种都不是好消息。

对于Windows中旧代码的问题,倒是情有可原,这些代码是在自动化测试真正得到认可前就开发出来了,而且它们很可能没有任何真正的测试基础架构。但是OneDrive占位符不是Windows的旧代码,它们是一套全新的功能。

我们可以原谅旧代码未经测试,但是没有充分的理由说新代码不应该有一组可靠的测试来验证基本功能?而且已知有缺陷的代码在修复之前肯定不应该合并,应该单独发给测试人员。

因此,Windows 10的开发仍然遵循类似于Windows 10之前的轨迹。随着功能的合并,稳定性和可靠性都会下降。然后依靠测试和稳定阶段解决问题,并将代码库重新打造成可以接受的状态。

不充分的自动化测试和对测试失败的忽视意味着Windows的开发人员无法确信改动和修复不会引发连锁反应。这就是在“请求”阶段突发出来的现象:随着更新的最终确定,可以接受的变更数量必须非常低,因为微软没有自信将每个改动的范围和影响相互独立开。只有大规模严谨的测试基础设施才能建立这样的信心:你知道改动是安全的,因为所有测试都运行成功了。无论微软针对Windows展开了怎样的测试,仅靠这些测试根本无法建立这样的信心。

但从其他方面来看,微软似乎确实有这种信心。

他们确实有很多测试,据我的了解完整的Windows测试周期需要数周的时间。他们也确实在贯彻完整的测试周期——只是并不是针对实际发布的那个版本。2018年10月的更新就是一个例子:代码建于9月15日,而发布在10月2日。无论是RS5的哪次构建经历了完整的测试周期,肯定不是我们实际使用的那个,因为完整的测试周期需要太长时间。

这是一种矛盾的姿态。如果他们对后继的代码改动很有信心,相信不会破坏任何东西,就可以在旧一点的版本上运行完整的测试周期。而且如果微软非常确信这些变化不会破坏任何东西,那么就不必在“请求”阶段严厉限制它们。

Windows 10本来可以是一台运行良好的机器

 

那么正确的方法是什么?

Windows的开发流程与真正的敏捷项目形成了鲜明的对比。

以Google为其广告服务器建立的流程为例:对Google来说,这是一个关键的基础架构,新的开发人员说他们为了修复一个小bug改动了代码,并看到这些改动在一天内进入了产品。当改动的代码提交到代码存储库时,它会自动重建并进行一系列测试。然后负责该代码区域的开发人员会审查改动,接受改动,并将其合并到主代码库中,最后再经过重新测试后部署到产品中。

当然,这样比有点不公平,因为发现bug的时候,云服务可以很容易地回滚代码变更。Windows系统中导致系统蓝屏的改动却很难撤消和恢复。但是,广告服务器毕竟是Google很关键的一项服务(毕竟这是Google主要的挣钱项目),而一个失误就会导致数百万美元的损失。Google在开发流程中采用了测试和自动化,这意味着刚刚进入公司的开发人员也可以参与这项服务的开发,并在几个小时内将改动部署到产品环境中,并且有信心保证正确。

这两家公司的开发思维方式有根本性的不同。在开发过程中新功能可能不稳定,但在将新功能合并到产品代码之前,必须满足非常高的质量标准。与其像微软一样采用“先合并bug,之后再慢慢修复”的方法,还不如确保代码在合并之前就尽可能做到零bug。

虽然云应用程序确实提供了一定的灵活性,但这种方法也可以在桌面软件中使用。例如,Google Chrome中的工作流程可以用来比较。Chrome的开发和beta版分支确实偶尔会出现bug,但总的来说,他们的代码质量始终可以达到“发布”的水平。实际上,Chrome团队的工作原则是,即使是最新版本的代码质量也应该达到发布的水平。你可以将Chrome的开发分支当成常规的浏览器,除了不同的图标外,你可能永远不会知道自己没有使用“稳定”的分支。广泛的自动化测试和审查流程保证了这一点:在整个开发过程中,Chrome的代码质量很高,没有我们在Windows上看到的质量下降和后续修补的工作。

Google还投资了基础设施来实现这一目标。它有一个分布式构建系统,可以在一千个核心上构建Chrome,因此可以在几分钟内完成整个构建。有条理地使用分支可以让合并变得更加容易和可预测。为了尽快发现bug和进行回归测试,Google实施了大量功能测试和性能测试。这些测试都花了很大精力,也都是至关重要的,因为它们可以让Google稳定且定期地发布Chrome。

 

Windows的开发流程一直都很糟糕

微软新的开发流程按比例增加了编写新功能所花费的时间,并缩短了稳定和修复这些功能的时间。如果刚开始时功能的质量很高,那么在新代码集成之前,测试基础设施可以支持新代码并提高标准,那就没问题了。

但到目前为止,以Windows 10的经历来看,微软尚未开发出维持这种新方法所需的流程和系统。

问题在于,即使现在将发布次数减少到一年一次也无法彻底解决问题。我经常感觉人们用有色眼镜回顾过去Windows开发的旧时代,但是,即使我们回顾Windows 7以及以前的时代,实际上也会看到与今天的情况非常相似的问题。通常的建议是:在Service Pack 1发布之前,不应升级到新版本的Windows。为什么?因为一般最初的版本都是bug累累且不稳定的状态,直到Service Pack 1才能解决大多数的问题。

不同之处并不在于新Windows开发流程比以前更糟了、或者旧方法提供的结果更好,现在是我们每年需要经历两次“等待Service Pack 1”的情况。在每次的更新中,微软认为代码对于企业用户来说足够好的时间点可能在距离最初发布功能更新后的3-4个月,也就是我们“新的”Service Pack 1的时间点。

因此,我们遇到了最糟糕的境地:

旧Windows开发方法下,新产品发布的第一天通常表现并不好。而新的Windows开发方法会让我们每年经历两次发布,而不是三年一次。一年中的大部分时间里,这个补丁发布之前的不稳定性都会陪伴在我们身边。

这些问题产生的根本原因,正在于微软糟糕的开发流程:先集成未经充分测试的功能代码,然后再慢慢解决所有问题。无论是每三年发布一次,还是每六个月发布一次,对Windows和用户来说都很不友好。

 

这并非Insider用户的工作

除了糟糕的开发流程外,第二个重要问题是微软测试的性质已经变了味。

微软过去拥有大量专门负责测试的人员,每个功能都可以分配到相应的开发人员和测试资源。这些测试人员中的许多人都在2014年被辞退或调职,因为微软认为负责创建功能的开发人员应该负责大部分测试工作。Windows Insider计划还专注于数百万用户提供的大量非正式测试结果,这比任何Windows的beta计划都要大得多。

 

虽然我们不确定旧的流程是否必然会导致数据丢失的bug,专门负责测试的人员也有可能不会测试数据被删除的特定场景。但是很明显,微软付出了大量精力用于处理Insider计划中非专业测试人员报告的bug。其实有人在这次十月份更新发布前的三个月就报告了数据丢失的bug,但很多关于该漏洞的报告本身质量就很差,不仅缺乏必要的细节,还会使用不恰当的术语,最终微软也只是忽略性地推出了“残缺”的更新版本。

当然,微软也未能在三个月内发现问题,那么即使加长开发周期也未必会有显著的改善——只是意味着bug被忽视的时间会从三个月延长到六个月。

微软也有承诺要改变Insider的反馈流程,允许bug报告者指出问题的严重性,从而让这些问题引起更多的关注。如果参与Insider计划的用户能够正确地使用严重性指标,那可能会有所帮助,但似乎并不足以解决其核心问题——太多质量低下的bug报告了,庞大的处理量下微软又怎么高效筛选?

这就与代码的质量问题密切有关。Insider计划的真正优势在于硬件和软件的多样性,它可以向外界暴露Windows,消除兼容性bug和驱动程序问题等等。然而,Insider的用户不应该成为“这个功能是否可以真正工作”测试的主力人员。但是,感觉这就是微软自以为“明智”的做法。

更糟糕的是,开发过程中代码质量确实出现了下降的事实,意味着预览版本一般都不适合个人电脑的日常应用。原因很简单,它们不够稳定。这会反过来贬低了Insider用户测试的价值:实际上,Insider用户并不会在所有的硬件和软件上使用新版本,因为他们并没有在主要的机器和所有硬件和软件上使用预览版本。他们只会在使用较少的辅助机器和虚拟机上测试而已。

 

投资工具必不可少

在像Windows一样复杂而庞大的系统内,建立类似于Chrome的测试基础架构是一项艰巨的任务。虽然Windows有些部分可以作为独立的组件广泛进行测试,但许多部件只有在作为完整系统的集成部件处理时才能进行有用的测试。其中一些,例如OneDrive文件同步功能,甚至需要依赖于外部网络服务来运行——这项工作一点也不简单。

Windows应该采纳的原则是:

代码应始终达到发布的质量,不是“经过几个月的修复”,而是“现在、随时可以发布”,这将是一个巨大的变化,但这是必要的。

从第一天开始,微软就需要进入一种状态:每个新更新都要达到产品的质量。功能更新不应该是一次大事件,用户几乎不会注意到。减少到一年发布一次、或每三年一次发布也达不到这样的效果,而且也不会有丝毫的帮助。

微软需要改变的是流程本身,而不是时间线。

原文:https://arstechnica.com/gadgets/2018/10/microsofts-problem-isnt-shipping-windows-updates-its-developing-them/

作者:Peter Bright,负责为Ars提供微软服务,包括编程和软件开发,Web技术和浏览器以及安全性。他曾在大英图书馆数字信息保存部门工作,致力于恢复和保护数字数据。在空闲时间里,他喜欢编写软件并偶尔为开源项目做贡献。

译者:弯月,责编:郭芮

IT人的致命自负