【畅言】软件工程的根本问题

个人认为是挺好的一篇帖子,转载一下:

发表于 2014-07-22 08:265626次阅读| 来源 CSDN26 条评论| 作者 李智勇
摘要:软件工程基于思维承载之物的特质,必然会有清晰的适用边界。但实际上恰恰与此相反,每当一种工程方法出世的时候,它的作用总是潜在的有扩大的趋势,似乎一旦锤子在手之后,所有身边的东西就都变成了应锤一锤的钉子。


软件工程存在什么问题?直接讲这一问题是:当一个人一个组织提倡一种方法时,不单要阐明方法自身,还要阐明方法自身的边界。而不是潜在的认为每一个自己创建的方法都是全能型的。

因为软件是一个庞杂的概念,基于其本质(参见:你真的了解软件开发的本质吗?)来看只有设计模式、正交、信息隐藏这样基于纯粹思维的东西有可能是共通于所有软件的,而软件工程由于更多的要基于思维承载之物的特质,所以必然会有比较清晰的适用边界。

所以说更合理的状态是不只要有通用的软件工程,也应该有适用于互联网的软件工程,适用于国防部软件的软件工程等,后者才是真正面向实践的。敏捷,CMMI这类东西在描述方法的同时既要描述自己的方法论本身,也要描述自己面临的约束和适用边界。最好能说清楚,自己哪些东西是变量,面对哪类现实时要进行何种伸缩。

但实际上恰恰与此相反,每当一种工程方法出世的时候,它的作用总是潜在的有扩大的趋势,似乎一旦锤子在手之后,所有身边的东西就都变成了应该锤一锤的钉子。

这有市场的因素,因为扩大了后相关生意更好做一些,也可以拿到一些奖励什么的,但更多的还是因为自身并不做太多思考。作为一种结果,过去十年里种种方法论兴亡过手,但开发水平很可能并没因此而提高多少。有点年纪的人大致应该记得由ISO到CMMI,再到敏捷的故事。当前应该是敏捷正处在兴盛期,但反敏捷的声音已经出现。

这进一步导致了一个奇葩的结果:现场的人非常反感软件工程,说:我一看到软件工程的书我就略过。很多人不再相信什么工程方法,更多的跟着感觉走,但与此同时则是《人月神话》中描述的猛犸象挣扎于焦油坑现象一再上演。

如何定义或寻找方法论的边界

那究竟怎样才能去定义或寻找一种方法论的适用边界?

如果把所有影响软件的因素都涵盖于软件工程之内,那么这事儿就变成无边界的了,财务、公司运营、市场营销全对软件有影响,如果把他们都包含到软件工程的概念内,软件工程就变成了四不像,什么都是可也什么都不是。

这点上可以向经济学家取经,经济学家研究经济学的方法是:先假设某些因素不发生变动,进而观察几个特定因素的变化和关系。

 我们可以先抽去商务因素、市场因素对软件的影响,寻找本质规律,用的时候再把商务因素、市场因素的权变加回来,看看如何弯曲本质规律以适应现实。

 好比我们随意画圆的时候画出的圆很容易是不理想的,但只要我们知道了圆的理想方程,我们就总可以画出尽可能完美的圆。

带边界和约束的方法论示例

下面说个例子来看看这种带边界和约束的方法论可以是什么样子。一般来讲做软件的时候我们总会谈到自顶向下与自底向上,前一个在设计上还有个专有名词叫:Big Up Design Front。理想中的瀑布模型是比较纯粹的自顶向下,而迭代则是自底向上多些。

从开发模型的角度看,它们看着是对立的,但如果你把开发模型看成是最佳组合人与事的方式时,这种对立就会消失。

瀑布模型下,把软件构建的活动分解为:需求、设计、编码、单元测试、集成测试、系统测试等环节,并期望逐步推进。这一开发模型似乎从诞生那一天起,就开始饱受批评,比如被指摘不能很好的应对需求变化等。但这一模型根基是工作分解间的时序和因果关系,其本身并无错处。

其成立前提和适应场景是:

  • 有人能够预先了解要开发产品的各种细节
  • 成员能力差异明显,构成明显的金字塔结构(少量极其优秀的人和较多能力较弱的人)

简单来讲就是在“想的人”对问题域非常清楚的情况下,比较彻底的分离想和做,最终“做的人”不用想。

虽然敏捷类思想不太考察这个维度,但事实上当组内一个人极度优秀,而其他人员平均水平比较差的时候,从项目的角度看,比较适合偏向瀑布,而不太适合导入敏捷类的迭代。

这个时候使用瀑布,可以获得更佳的生产率---当然你不能走极端,把瀑布绝对化。

但同样是使用瀑布模型如果上面的条件不具备,就会导致灾难:

没有合适的人确定需求,大部分勉强决定的规格可能完全没有意义。设计如果只是纸上谈兵,编码的人又无法修改,那么就会发生无休止的讨论,加剧内耗。

也就是说,假如说团队中的成员A,在经过一定的思考后可以预见到当前的实现方法会导致性能问题,那么就比较适合预先把应对措施定义下来(即使是Big Up Design Front),而不能等迭代出问题再进行解决,后者的内耗明显是高的。

从上面的例子里我们可以得到两个彼此关联的结论:

  • 人和项目特征决定了开发模型,而非反过来需要根据开发模型来调整人员配置等。这是因为在特定时空背景下,调整人和项目特征的可能性小。
  • 假如人和项目的变化是连续的,那么无疑的绝对的瀑布和迭代之间程度的变化也是连续的。作为结果,大多时候最优的开发模型必然既不是绝对的瀑布,也不是绝对的迭代,而是一种具体情境下的选择,可能偏向于瀑布,也可能偏向于迭代。

开发模型的价值就在于,如果我们能够在连续中找到这一最佳平衡点,在这一点上内耗最低。

这种对方法论的描述无疑是与许多教科书上相差很大的,但我比较相信这才是一种正确的方式。

结束语:关于行文方法

近来在《畅言》这个栏目里发了几篇文章,有时候会被抱怨看不懂,装什么的。我对回这类评论没什么兴趣,但比较想解释下自己的写作方法。

我写东西一般是《几何原本》式的:基于几个显然成立的假设,进行逻辑推理,只在特别需要的时候求助于数据和个人判断。这在IT圈子里好像有点特别,我不知道还有谁这么干(大家如果看过《大道致易》可能会发现周爱民同学有点这个路数)。这么写的好处是逻辑严谨;坏处是会比较抽象,读起来没故事的感觉,会觉得比较硬。我比较相信读者如果跟着走下来会有些收获的。

我个人其实是个懂技术的管理人员,因为喜欢哲学,所以对技术、对管理等做了些哲学式的思考,有点偏理论。接下来会零散的观点陆续整理下,发在这栏目里,与大家切磋下,这些观点符合逻辑,可能会比较另类,但只要与逻辑和事实相符,个人其实不太在意与多少人观点不一致,何况在思考上世上也没那么多高手,人云亦云的还是多些。再接下来应该会在实践V众投上花更多时间,偏宏观,本质的思考类事情会做的少了。写作风格上会尽量控制,让它容易懂些。

当然我也很欢迎大家指出真正错误的地方,有的话也可以发在畅言这个栏目,毕竟有这种真正的切磋,才会有真正的进步么,瞎骂的就算了。

作者介绍:李智勇,V众投发起人,《完美软件开发:方法与逻辑》作者。目前正在免费发布《程序员生存定律》,微博:李智勇SZ,微信:vfacebook。


《畅言》第八期:【[畅言]让软件公司的管理多一点“灵魂”】不少软件公司的成功是源自产品、人口红利,而不是因为管理,甚至有的公司的管理带来的是负值。这样的公司之所以成功,只是因为正面值太大。而另外一面,现实中很多的软件公司,其管理很可能已经陷入了困境。而这是慢性毒药,带来了恶性循环。如何解决?

《畅言》第九期:【[畅言]你真的了解软件开发的本质吗?】我们总是喜欢用自己的经历来定义软件是什么以及判断标准,但如果这种经历来自完全不同的两个领域,并且互相矛盾,那么就有可能让大家吵来吵去……是的,各位在忙于解决具体问题时,谁还会想到谈谈软件开发的本质?

《畅言》第十期:【[畅言]程序员可以只关心技术么?】不少程序员爱维护喜欢的技术,虽然他们说的有道理,但程序员价值的实现并不取决于技术。模式不一样,程序员价值也不一样,而这也暗含了程序员生涯的两个进阶模式,读完此文,相信你会重新思考个人生涯发展方向。

《畅言》是CSDN新栏目,供大家各抒己见。只要你看完CSDN文章或评论后有话说,都可以通过电子邮件(zhangyong@csdn.net)投稿,从而获得上CSDN首页表达自己观点、想法的机会。《畅言》不怕观点“雷人”,只要你逻辑表达清楚、数据引用可靠,你敢投稿,我们就敢首页!欢迎大家畅所欲言。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值