历史上的重大软件BUG启示录第9篇---微软的硬件尝试
微软公司看到了个人播放器的前景,也想从这个市场分一杯羹,因此微软公司在2006年推出了第一代类似iPod的产品Zune。
虽然在个人电脑操作系统方面,windows操作系统占据了绝大多数份额,但是Zune却远不如创新不断的iPod销量高。Zune 在销量最高的时候也只是拿下了美国便携播放器市场份额 9%,远远低于 iPod 的 63%。销量惨淡不说,Zune的软件BUG又为苹果公司送了助攻。
2008年的最后一天,微软的30G存储版本Zune却遇到大规模无法启动问题。在这一天内,无论出于什么原因,只要用户重启了Zune,Zune就会卡在开机LOGO界面中无法启动。
互联网戏剧性的加剧了这个BUG的传播,因为大批网友在网上描述了这个问题,寻求解决方案,其它网友纷纷用自家Zune测试,成功的测试出只有30G存储版本Zune会遇到无法启动问题,顺带着大批设备变砖。
微软也是紧急出动,为了使事态不扩大而努力的工作着:先是发布公告称自己正在卖力的解决这个问题中,大家不必恐慌,会尽快通过Zune官方网站公布解决方案;随后,微软给出了问题原因和临时解决方案。
30GB存储版本Zune无法启动的原因在于Zune播放器的内置时钟驱动软件有BUG,使其无法正确处理闰年的最后一天(2008 年是闰年)!临时解决方案就一个字:等!你没看错,就是等。等到Zune电量耗尽关机,然后再等到2009年1月1日上午7点后,充电开机就能自然解决。
闰年BUG是比较常见的,究其原因,是瑞年不常见并且定义容易迷惑人引起的。不要小看了闰年,我们看一下闰年的定义,满足以下两个条件中任意一个的,为闰年:
- 年份能被4整除,且不能被100整除
- 能被400直接整除
你能从这个定义中写出一个正确的闰年判断方法吗?可以在私下试试,我们还是回过头来看微软Zune的时钟驱动BUG是怎么出现的。
微软30G存储版本Zune使用的时钟芯片是飞思卡尔的,有网友找到了该时钟驱动源代码,截取出错代码如下所示。
该代码用于将日期(days)转换成年份。由于闰年有366天,而平年只有365天,所以要分别处理这两个年份逻辑。当循环处理到2008年时,程序在执行第3行if(DateTime.IsLeapYear(year))后,判断出2008年为闰年,然后执行第5行if(days > 366),软件BUG就出在这里!在2008年的最后这天,变量days中恰好是366,不能满足第5行的”days > 366”这个条件,然后程序转到第1行,然后执行第三行,再执行第5行,发现条件不成立再次执行第1行,如此死循环!
while(days > 365)
{
if(DateTime.IsLeapYear(year))
{
if(days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}
编程无小事,任一点疏忽都会带来难以估量的损失!另外,这个BUG对我们的测试也很有启发,我想飞思卡尔和微软的开发人员一定详细的测试过这个代码,但他们都忽视了“润年最后一天”这个边界条件!这告诉我们验证逻辑时,切勿盲目自信,应重点关注那些不常使用的点上,往往这些点才是问题频频爆发的原因。
Zune随后的发展如何呢?2011年10月4日微软宣布,停止生产Zune,2013年11月22 Zune商店关闭,至此微软在个人播放器领域的尝试告一段落。这或许并不是微软的错,因为随着智能手机的普及,单独的便携式播放器的份额被智能手机严重蚕食,即便是苹果的iPod也逐渐成为了边缘产品,被归结到了“其它设备”类,想来离全面停产也不远了。
微软停止生产Zune后,在其它硬件领域有了新的突破,那就是微软surface系列,包括平板和笔记本,成为了Windows系统设备的标杆!
历史上的重大软件BUG启示录第9篇---微软的硬件尝试的更多相关文章
- JVM系列.历史上出现过的Java虚拟机
HotSpot绝对是当今商用虚拟机的王者,但是在Java历史上出现过很多Java虚拟机,这篇文章就来整理下历史上出现过的Java虚拟机以及他们的特性. Sun Classic Sun Classic虚 ...
- 史上最臭名昭著五大软件Bug
在现今数字年代,计算机bug不但困扰着每个程序员,更会无可避免影响我们的生活,小到每个人的衣食住行,大到国家经济,世界局势.随着我们的生活方式渐渐的数字化.互联网化,数字世界的找虫和杀虫就变得越来越重 ...
- Wine——在Linux上运行Windows软件
官网:https://www.winehq.org/ 参考: wikipedia 教你使用Wine在Linux上运行Windows软件 如何安装和使用Wine,以便在Linux上运行Windows应用 ...
- C语言中史上最愚蠢的Bug
C语言中史上最愚蠢的Bug 本文来自“The most stupid C bug ever”,很有意思,分享给大家.我相信这样的bug,就算你是高手你也会犯的.你来看看作者犯的这个Bug吧.. 首 ...
- Linux历史上线程的3种实现模型
一.概述 这里以Linux为例.Linux历史上,最开始使用的线程是LinuxThreads,但Li ...
- UWP Windows历史上最漂亮的UWP框架出炉!!!
UWP Windows历史上最漂亮的UWP框架出炉!!! 本框架基于微软的开源项目WTS开发,并在其基础上增加了FDS(流畅设计元素,高光.亚克力等).多语言系统.沉浸式体验(扩展内容到标题栏) 同时 ...
- Rokid开发者社区skill之【历史上的今天】之简介+玩法+设计+实现+心得
Skill简介: 来源:好奇心.探索欲.趣味性: 资源:百度百科: 方式:实时获取,自动更新: 技能玩法: 想要进入历史上的今天这个skill,则对若琪说:若琪,打开历史上的今天. 想要了解某天的历史 ...
- Rokid开发者社区skill之【历史上的今天】
技能名称:历史上的今天 入口词:打开历史上的今天 语音交互:(有些是先写上) { "intents": [ { "intent": "PAUSE_HI ...
- jQuery+Ajax获取百度百科历史上的今天
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
随机推荐
- Web安全大揭秘
web安全大揭秘,通常会有那些web安全问题呢? 1,xss 2,sql注入 3,ddos攻击
- python16_day28【crm只读、权限、堡垒机】
一.只读 二.万能权限 三.堡垒机
- 转载Liferay PortletPreference store()方法研究
我们对于PortletPreference 的store()用的非常广泛,很多情况下,我们一般对其进行一些设定,然后最后调用store()存储之,类似以下代码: PortletPreferences ...
- TFS2015源代码管理器无法建立团队项目的问题
最近在服务器安装了微软最新版的TFS2015 正版要钱,网络上还没有能找到可用的key,因此我只能使用试用版. 安装完成后,使用我本地的vs2013 vs2012 vs2010 vs2014 ...
- TED #02#
Amanda Palmer: The art of asking 1. I think people have been obsessed with the wrong question, which ...
- SQL学习笔记四(补充-2)之MySQL多表查询
阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 #建表 create table depart ...
- Mysql性能调优工具Explain结合语句讲解
Explain简称执行计划,可以模拟SQL语句,来分析查询语句或者表结构是否有性能瓶颈.Explain的作用有哪些,可以看到哪些?可以看到表的读取顺序,数据读取操作的操作类型,哪些索引可以使用,哪些索 ...
- bzoj1615 / P2903 [USACO08MAR]麻烦的干草打包机The Loathesome Hay Baler
P2903 [USACO08MAR]麻烦的干草打包机The Loathesome Hay Baler 细节题.$O(n^{2})$的$bfs$可过. #include<iostream> ...
- 20145326实验四 Android开发基础
20145326实验四 Android开发基础 一.实验内容及步骤 安装 JDK 并配置 JDK 环境变量 找到之前path变量中的jdk文件所在位置并复制. 并用复制的变量名新建一个 JAVA_HO ...
- CGI, FCGI, SCGI, WSGI 释异
IKI Links: CGI - http://en.wikipedia.org/wiki/Common_Gateway_Interface FCGI - http://en.wikipedia.or ...