Language agnostic 环路中的技术非终止条件
我们大多数人都知道循环不应该有非终止条件。例如,这个C#循环有一个非终止条件:i的任何偶数值。这是一个明显的逻辑错误Language agnostic 环路中的技术非终止条件,language-agnostic,loops,infinite-loop,Language Agnostic,Loops,Infinite Loop,我们大多数人都知道循环不应该有非终止条件。例如,这个C#循环有一个非终止条件:i的任何偶数值。这是一个明显的逻辑错误 void CountByTwosStartingAt(byte i) { // If i is even, it never exceeds 254 for(; i < 255; i += 2) { Console.WriteLine(i); } } 现在,假设你给它喂这个东西: class InfiniteEmptyStream:Str
void CountByTwosStartingAt(byte i) { // If i is even, it never exceeds 254
for(; i < 255; i += 2) {
Console.WriteLine(i);
}
}
现在,假设你给它喂这个东西:
class InfiniteEmptyStream:Stream
{
// ... Other members ...
public override int Read(byte[] buffer, int offset, int count) {
Array.Clear(buffer, offset, count); // Output zeros
return count; // Never returns -1 (end of stream)
}
}
或者更现实地说,可能是一个从外部硬件返回数据的流,在某些情况下可能返回大量的零(例如坐在桌子上的游戏控制器)。无论哪种方式,我们都有一个无限循环。这种特殊的非终止条件很突出,但有时并不突出
一个完全真实的例子,比如我正在编写的一个应用程序。无穷无尽的零流将被反序列化为无限的“空”对象(直到集合类或GC抛出异常,因为我已超过20亿项)。但这将是一个完全出乎意料的情况(考虑到我的数据源)
绝对没有非终止条件有多重要?这对“健壮性”有多大影响?如果它们只是“理论上”不终止(如果异常表示隐式终止条件,可以吗)?应用程序是否商业化有关系吗?是否公开分发?如果无法通过公共接口/API访问有问题的代码,这有关系吗
编辑:
我所关注的主要问题之一是不可预见的逻辑错误,它会造成非终止条件。通常,如果您确保不存在非终止条件,那么您可以更优雅地识别或处理这些逻辑错误,但这值得吗?什么时候?这是一个与信任正交的问题。您要么“信任”您的数据源,要么不信任
如果您信任它,那么您可能希望尽最大努力处理数据,无论数据是什么。如果它永远给你零分,那么它给你带来了一个太大的问题,你的资源无法解决,你把所有的资源都花在了上面,结果失败了。您说这是“完全出乎意料的”,所以问题是,对于您的应用程序来说,仅仅因为内存不足而“完全出乎意料”是否可以。还是说这真的不可能
如果您不信任您的数据源,那么您可能希望人为地限制您将尝试的问题的大小,以便在系统内存不足之前失败
在任何一种情况下,都有可能以这样一种方式编写应用程序,即从内存不足异常中优雅地恢复
无论哪种方式,这都是一个稳健性问题,但是由于问题太大而无法解决(您的任务不可能完成)而导致的失败通常被认为比因为某个恶意用户向您发送了一个零流(您接受了某个脚本kiddie DoS攻击者发出的不可能完成的任务)而导致的失败更容易接受。您是否“信任”你的数据源,或者你没有
如果您信任它,那么您可能希望尽最大努力处理数据,无论数据是什么。如果它永远给你零分,那么它给你带来了一个太大的问题,你的资源无法解决,你把所有的资源都花在了上面,结果失败了。您说这是“完全出乎意料的”,所以问题是,对于您的应用程序来说,仅仅因为内存不足而“完全出乎意料”是否可以。还是说这真的不可能
如果您不信任您的数据源,那么您可能希望人为地限制您将尝试的问题的大小,以便在系统内存不足之前失败
在任何一种情况下,都有可能以这样一种方式编写应用程序,即从内存不足异常中优雅地恢复
无论哪种方式,这都是一个稳健性问题,但由于问题太大而无法解决(您的任务不可能完成)而导致的失败通常被认为比因为某个恶意用户向您发送了一个零流(您接受了某个脚本kiddie DoS攻击者发出的不可能完成的任务)而导致的失败更容易接受诸如此类的事情必须根据具体情况来决定。如果有额外的健全性检查可能是有意义的,但要使每一段代码都完全万无一失,工作量太大了;而且,要预测傻瓜们会想出什么主意并不总是可能的。诸如此类的事情必须根据具体情况来决定。如果有额外的健全性检查可能是有意义的,但要使每一段代码都完全万无一失,工作量太大了;而且,要预测傻瓜们的想法并不总是可能的 要么“信任”数据源,要么不信任 我认为您要么“支持”与该数据源一起使用的软件,要么不支持。例如,我见过一些软件没有处理内存不足的情况:但该软件不“支持”内存不足(或者不太明确地说,该系统不支持内存不足);因此,对于该系统,如果出现内存不足的情况,修复方法是减少系统负载或增加内存(而不是修复软件)。对于该系统,处理内存不足不是一个要求:一个要求是管理系统上的负载,并为给定负载提供足够的内存 要么“信任”数据源,要么不信任 我认为您要么“支持”与该数据源一起使用的软件,要么不支持。例如,我见过一些软件没有处理内存不足的情况:但该软件不“支持”内存不足(或者不太明确地说,该系统不支持内存不足);因此,对于该系统,如果出现内存不足的情况,修复方法是减少系统负载或增加内存(而不是修复软件)。对于该系统,处理内存不足不是一个要求:一个要求是管理系统上的负载,并为给定负载提供足够的内存 呵呵
class InfiniteEmptyStream:Stream
{
// ... Other members ...
public override int Read(byte[] buffer, int offset, int count) {
Array.Clear(buffer, offset, count); // Output zeros
return count; // Never returns -1 (end of stream)
}
}