理论计算机科学什么时候有用?
在课堂上,我们学习了停机问题、图灵机、归约等。很多同学说这些都是抽象的、无用的概念,了解它们没有任何实际意义(也就是说,一旦课程结束,你就会忘记它们)结束并且不会丢失任何东西)。
为什么理论有用? 您在日常编码中使用过它吗?
In class, we learned about the halting problem, Turing machines, reductions, etc. A lot of classmates are saying these are all abstract and useless concepts, and there's no real point in knowing them (i.e., you can forget them once the course is over and not lose anything).
Why is theory useful? Do you ever use it in your day-to-day coding?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
真实的故事:
当我从研究生院毕业后找到第一份编程工作时,我工作的公司的老板都是飞行员。 我被录用几周后,其中一个人问了我这个问题:
我认真地认为他是在考验我对旅行商问题和 NP 完备性的了解。 但事实证明他不是。 他对此一无所知。 他真的想要一个能够找到最短路径的程序。 当我解释说存在 106 个阶乘解并且找到最佳解是一个众所周知的计算难题时,他感到很惊讶。
这就是一个例子。
True story:
When I got my first programming job out of graduate school, the guys that owned the company that I worked for were pilots. A few weeks after I was hired, one of them asked me this question:
I seriously thought he was quizzing me on my knowledge of the Traveling Salesman Problem and NP-Completeness. But it turns out he wasn't. He didn't know anything about it. He really wanted a program that would find the shortest path. He was surprised when I explained that there were 106-factorial solutions and finding the best one was a well-known computationally intractable problem.
So that's one example.
当我大学毕业时,我认为我和其他人一样:“我拥有计算机科学学士学位,其他很多人也是如此,我们基本上都可以做同样的事情。” 我最终发现我的假设是错误的。 我脱颖而出,与我的背景有很大关系——尤其是我的学位。
我知道有一个“轻微”的区别,因为我拥有计算机科学的“BS”,因为我的大学是全国第一所获得计算机科学学位课程认证的大学之一(据说在 1987 年排名第二),而且我以第二级毕业获得该认证。 当时,我并不认为这有什么大不了的。
我还注意到,在高中和大学期间,我在计算机科学方面表现得特别好——比我的同龄人好得多,甚至比我的许多老师都好。 我被要求了很多帮助,做了一些辅导,被要求帮助一个研究项目,并被允许在没有人的情况下进行独立研究。 我很高兴能够提供帮助,但我并没有过多考虑其中的区别。
大学毕业后(美国空军学院),我在空军服役了四年,其中两年是在申请计算机科学学位。 在那里,我注意到我的同事中很少有人拥有与计算机相关的学位,甚至没有接受过计算机相关的培训。 空军派我参加了五个月的认证培训,在那里我再次发现缺乏学位或培训。 但在这里我开始注意到差异——很明显,我遇到的许多人并不真正知道自己在做什么,其中包括受过培训或拥有学位的人。 请允许我举例说明。
参加我的空军认证培训的共有十三个人(包括我在内)。 作为空军军官或同等人员,我们都拥有学士学位。 根据年龄和级别,我处于中间位置(在 6 个 O-1 和 6 个 O-3 及以上级别中,我是 O-2)。 在本次培训结束时,空军给我们所有人颁发了橡皮图章,让我们所有人都同样有能力为国防部的任何部门采购、建造、设计、维护和操作任何计算机或通信系统。
然而,在我们十三个人中,只有六人拥有任何形式的计算机相关学位; 其他七人拥有从航空学到化学/生物学再到心理学的学位。 在我们六个拥有计算机科学学位的人中,我了解到其中两个人从未编写过任何类型的程序,并且从未使用过计算机(写论文、玩游戏等)。 我了解到,我们另外两个人在计算机科学学位课程期间在一台计算机上编写了一个程序。 只有我和另外一个人编写了不止一种程序或使用了不止一种计算机——事实上,我们发现我们两个编写了很多程序并使用了多种计算机。
五个月的培训快结束时,我们班被分配了一个编程项目,我们被分成四个小组分别进行。 我们的导师为了公平地分配“编程人才”而对班级进行了划分,他们分配了团队领导、技术领导和开发人员的角色。 每个小组都有一周的时间(在 Ada 中)在教练提供的飞行力学库之上为飞行模拟器实现一个全屏、基于文本的用户界面(这是 1990 年)。 我被任命为我的四人团队的技术主管。
我的团队领导(没有计算机学位)要求我们其他三个人将项目划分为任务,然后将其中的三分之一分配给我们每个人。 我在第一天的中间完成了第三个任务,然后用这一天剩下的时间帮助我的另外两个队友,与我的团队领导交谈(BSing;^),并在我的电脑上玩。
第二天早上(第二天),我的团队负责人私下告诉我,我们的另外两个队友没有取得任何进展(其中一个实际上无法写出可以编译的“if”语句),他让我承担他们的工作。 我在下午三点左右完成了整个项目,我的团队在当天剩下的时间里都在驾驶模拟器。
另一个拥有类似计算机科学学位的人也被任命为他团队的技术主管,他们在第三天结束时完成了工作。 他们还开始驾驶模拟器。 到本周末,其他两支球队尚未完成,甚至没有取得重大进展。 我们不被允许帮助其他球队,所以就这样了。
与此同时,到了第三天中午,我注意到飞行模拟器似乎表现“错误”。 因为我的一个同学拥有航空学位,所以我向他询问了这件事。 他很困惑,然后承认他实际上不知道是什么让飞机飞起来!?! 我当时就傻眼了! 事实证明,他的整个学位课程都是关于安全和坠机调查的——飞行背后没有真正的数学或科学。 另一方面,我可能辅修了航空学(还记得美国空军协会吗?),但我们设计了机翼并进行了真正的风洞测试。 因此,我悄悄地花了一周剩下的时间重写教练提供的飞行力学库,直到模拟器“正确”飞行。
从那时起,我花了近二十年的时间作为承包商,偶尔作为雇员,一直从事软件开发以及相关活动(DBA、架构师等)。 我不断地发现更多相同的东西,最终我放弃了我年轻时的假设。
那么,我究竟发现了什么? 并不是每个人都是平等的,这没关系——我不是一个更好的人,因为我可以有效地编程,但如果这正是你需要我做的,我会更有用。 我了解到我的背景真的很重要:
成长于电工和电气工程师家庭,
建筑电子套件,
阅读学校/公共图书馆中的每一本计算机书籍,因为我无法使用真正的计算机,
然后搬到一个新城市,我的高中确实有电脑,
然后得到我自己的电脑作为礼物,
去拥有多种不同尺寸和类型的计算机(PC 到大型机)的学校,
获得一所非常好的工程学校认可的学位,
必须在不同类型的计算机上用不同语言编写大量程序,
必须编写困难的程序(例如我自己的具有自定义汇编语言的虚拟机,或霍夫曼压缩实现等),
必须自己解决问题,
用零件组装我自己的计算机并安装所有软件,
最终
,我了解到我的能力建立在从电气层面上了解计算机如何工作的基础上——分立电子元件、电路、子系统、接口、协议、位、字节、处理器、设备、驱动程序、库、程序、系统、网络,直到我现在经常工作的大型企业级企业集团。 所以,当这该死的东西行为不端时,我确切地知道如何和为什么。 我知道什么不能做,什么可以做。 我对已经做过的事情、尝试过的事情以及相对尚未探索的事情了解很多。
最重要的是,在我了解了这一切之后,我发现我什么都不知道。 面对所有可能知道的事情,我的知识是微乎其微的。
我对此很满意。 但我建议你尝试一下。
When I graduated from college, I assumed that I was on par with everyone else: "I have a BS in CS, and so do a lot of other people, and we can all do essentially the same things." I eventually discovered that my assumption was false. I stood out, and my background had a lot to do with it--particularly my degree.
I knew that there was one "slight" difference, in that I had a "B.S." in CS because my college was one of the first (supposedly #2 in 1987) in the nation to receive accreditation for its CS degree program, and I graduated in the second class to have that accreditation. At the time, I did not think that it mattered much.
I had also noticed during high school and in college that I did particularly well at CS--much better than my peers and even better than many of my teachers. I was asked for help a lot, did some tutoring, was asked to help with a research project, and was allowed to do independent study when no one else was. I was happy to be able to help, but I did not think much about the difference.
After college (USAFA), I spent four years in the Air Force, two of which were applying my CS degree. There I noticed that very few of my coworkers had degrees or even training related to computers. The Air Force sent me to five months of certification training, where I again found a lack of degrees or training. But here I started to notice the difference--it became totally obvious that many of the people I encountered did not REALLY know what they were doing, and that included the people with training or degrees. Allow me please to illustrate.
In my Air Force certification training were a total of thirteen people (including me). As Air Force officers or the equivalent, we all had BS degrees. I was in the middle based on age and rank (I was an O-2 amongst six O-1s and six O-3s and above). At the end of this training, the Air Force rubber-stamped us all as equally competent to acquire, build, design, maintain, and operate ANY computer or communication system for ANY part of the Department of Defense.
However, of the thirteen of us, only six had any form of computer-related degree; the other seven had degrees ranging from aeronautics to chemistry/biology to psychology. Of the six of us with CS degrees, I learned that two had never written a program of any kind and had never used a computer more than casually (writing papers, playing games, etc.). I learned that another two of us had written exactly one program on a single computer during their CS degree program. Only one other person and myself had written more than one program or used more than one kind of computer--indeed, we found that we two had written many programs and used many kinds of computers.
Towards the end of our five-month training, our class was assigned a programming project and we were divided into four groups to separately undertake it. Our instructors divided up the class in order to spread the "programming talent" fairly, and they assigned roles of team lead, tech lead, and developer. Each group was given a week to implement (in Ada) a full-screen, text-based user interface (this was 1990) for a flight simulator on top of an instructor-provided flight-mechanics library. I was assigned as tech lead for my team of four.
My team lead (who did not have a computer degree) asked the other three of us to divide up the project into tasks and then assigned a third of them to each of us. I finished my third of the tasks by the middle of that first day, then spent the rest of the day helping my other two teammates, talking to my team lead (BSing ;^), and playing on my computer.
The next morning (day two), my team lead privately informed me that our other two teammates had made no progress (one could not actually write an "if" statement that would compile), and he asked me to take on their work. I finished the entire project by mid-afternoon, and my team spent the rest of the day flying the simulator.
The other guy with the comparable CS degree was also assigned as a tech lead for his team, and they finished by the end of day three. They also began flying their simulator. The other two teams had not finished, or even made significant progress, by the end of the week. We were not allowed to help other teams, so it was left at that.
Meanwhile, by the middle of day three, I had noticed that the flight simulator just seemed to behave "wrong". Since one of my classmates had a degree in aeronautics, I asked him about it. He was mystified, then confessed that he did not actually know what made a plane fly!?! I was dumbfounded! It turns out that his entire degree program was about safety and crash investigations--no real math or science behind flight. On the other hand, I had maybe a minor in aeronautics (remember USAFA?), but we had designed wings and performed real wind tunnel tests. Therefore, I quietly spent the rest of the week rewriting the instructor-provided flight-mechanics library until the simulator flew "right".
Since then, I have spent nearly two decades as a contractor and occasionally as an employee, always doing software development plus related activities (DBA, architect, etc.). I have continued to find more of the same, and eventually I gave up on my youthful assumption.
So, what exactly have I discovered? Not every one is equal, and that is okay--I am not a better person because I can program effectively, but I am more useful IF that is what you need from me. I learned that my background really mattered:
growing up in a family of electricians and electrical engineers,
building electronics kits,
reading LITERALLY every computer book in the school/public libraries because I did not have access to a real computer,
then moving to a new city where my high school did have computers,
then getting my own computer as a gift,
going to schools that had computers of many different sizes and kinds (PCs to mainframes),
getting an accredited degree from a VERY good engineering school,
having to write lots of programs in different languages on different kinds of computers,
having to write hard programs (like my own virtual machine with a custom assembly language, or a Huffman compression implementation, etc.),
having to troubleshoot for myself,
building my own computers from parts and installing ALL the software,
etc.
Ultimately, I learned that my abilities are built on a foundation of knowing how computers work from the electrical level on up--discrete electronic components, circuitry, subsystems, interfaces, protocols, bits, bytes, processors, devices, drivers, libraries, programs, systems, networks, on up to the massive enterprise-class conglomerates that I routinely work on now. So, when the damn thing misbehaves, I know exactly HOW and WHY. And I know what cannot be done as well as what can. And I know a lot about what has been done, what has been tried, and what is left relatively unexplored.
Most importantly, after I have learned all that, I have learned that I don't know a damned thing. In the face of all that there is potentially to know, my knowledge is miniscule.
And I am quite content with that. But I recommend that you try.
当然,它很有用。
想象一下开发人员正在开发模板引擎。 你知道这样的事情......
一开始很简单,用一个厚颜无耻的小正则表达式来执行替换。
但渐渐地,模板变得更加奇特,开发人员包括了模板化列表和字符串映射的功能。 为了实现这一目标,他编写了一个简单的小语法并生成了一个解析器。
模板引擎变得非常狡猾,最终可能会包含条件逻辑语法,以根据参数的值显示不同的文本块。
具有计算机科学理论背景的人会认识到模板语言正在慢慢变得图灵完整,也许解释器模式将是实现它的好方法。
为模板构建了解释器后,计算机科学家可能会注意到大多数模板请求都是重复的,一遍又一遍地重新生成相同的结果。 因此开发了一个缓存,所有请求在执行昂贵的转换之前都会通过缓存进行路由。
此外,某些模板比其他模板复杂得多,并且需要更长的时间来渲染。 也许有人想到在渲染每个模板之前估计它的执行情况。
可是等等!!! 团队中有人指出,如果模板语言真的是图灵完备的,那么估计每个渲染操作的执行时间的任务就是停机问题的一个实例! 哎呀,不要这样做!
理论在实践中的作用是,所有的实践都是基于理论的。 理论上来说。
Sure, it's useful.
Imagine a developer working on a template engine. You know the sort of thing...
It starts out simple, with a cheeky little regular expression to peform the replacements.
But gradually the templates get a little more fancy, and the developer includes features for templatizing lists and maps of strings. To accomplish that, he writes a simple little grammar and generates a parser.
Getting very crafty, the template engine might eventually include a syntax for conditional logic, to display different blocks of text depending on the values of the arguments.
Someone with a theoretical background in CS would recognize that the template language is slowly becoming Turing complete, and maybe the Interpreter pattern would be a good way to implement it.
Having built an interpreter for the templates, a computer scientist might notice that the majority of templating requests are duplicates, regenerating the same results over and over again. So a cache is developed, and all requests are routed through the cache before performing the expensive transformation.
Also, some templates are much more complex than others and take a lot longer to render. Maybe someone gets the idea to estimate the execution of each template before rendering it.
But wait!!! Someone on the team points out that, if the template language really is Turing complete, then the task of estimating the execution time of each rendering operating is an instance of the Halting Problem!! Yikes, don't do that!!!
The thing about theory, in practice, is that all practice is based on theory. Theoretically.
我最常用的东西:
了解 图灵机等。我认为这很重要,因为它定义了我们所有人操作的约束。 欣赏这一点很重要。
The things I use most:
As to that stuff on Turing machines etc. I think it is important because it defines the constraints under which we all operate. Thats important to appreciate.
这就是学习代数和学习如何使用计算器之间的区别,
如果您了解代数,您意识到同一问题可能会以不同的形式表现出来,并且您了解将问题转化为更简洁形式的规则(
如果您只知道如何使用)要使用计算器,您可能会在以下问题上浪费大量时间:(a)已经解决,(b)无法解决,或者(c)与您不知道的其他问题(已解决或未解决)类似不认识,因为它以不同的形式
假装,暂时,计算机科学是物理学......这个问题会显得愚蠢吗?
it's the difference between learning algebra and being taught how to use a calculator
if you know algebra, you realize that the same problem may manifest in different forms, and you understand the rules for transforming the problem into a more concise form
if you only know how to use a calculator, you may waste a lot of time punching buttons on a problem that is either (a) already solved, (b) cannot be solved, or (c) is like some other problem (solved or unsolved) that you don't recognize because it's in a different form
pretend, for a moment, that computer science is physics... would the question seem silly?
我的一个朋友正在研究一种带有一些模板的语言。 我被邀请去做一些咨询。 我们讨论的一部分是模板功能,因为如果模板是图灵完整的,他们将必须真正考虑 VM 式属性以及他们的编译器如何/是否支持它。
我的故事是这样的:自动机理论仍然被教授,因为它仍然具有相关性。 停止问题仍然存在,并且限制了您的操作。
现在,这些事情与数据库管理员敲定 C# 代码有关吗? 可能不会。 但当你开始进入更高的水平时,你会想要了解你的根源和根源。 基础。
A friend of mine is doing work on a language with some templates. I was asked in to do a little consulting. Part of our discussion was on the template feature, because if the templates were Turing complete, they would have to really consider VM-ish properties and how/if their compiler would support it.
My story is to this point: automata theory is still taught, because it still has relevance. The halting problem still exists and provides a limit to what you can do.
Now, do these things have relevance to a database jockey hammering out C# code? Probably not. But when you start moving to a more advanced level, you'll want to understand your roots & foundations.
虽然我不直接将它们应用到日常工作中,但我知道我接受的正规计算机科学教育影响了我的思维过程。 我当然从一开始就避免了某些错误,因为我从正式方法中吸取了教训。
当他们学习的时候,它可能看起来毫无用处; 但我敢打赌,你的同学最终会遇到一个问题,他们会使用所学的内容,或者至少使用其背后的思维模式...
打蜡...打蜡...打蜡...打蜡……这和空手道有什么关系呢?
Although I don't directly apply them in day-to-day work, I know that my education on formal computer science has affected my thinking process. I certainly avoid certain mistakes from the onset because I have the lessons learned from the formal approaches instilled in me.
It might seem useless while they're learning it; but I bet your classmate will eventually comes across a problem where they'll use what they were taught, or at least the thinking patterns behind it...
Wax on... Wax off... Wax on... Wax off... What does that have to do with Karate, anyways?
在一份工作中,我的任务是改进配电模型的网络跟踪算法,因为他们使用的算法太慢了。 三相网络本质上是三个 n 树(因为电力网络中不允许出现环路)。 网络节点位于数据库中,一些原始团队无法弄清楚如何构建内存中模型,因此跟踪是通过数据库上的连续深度 SELECT 完成的,并在每个阶段进行过滤。 因此,要追踪一个节点(距变电站十个节点)至少需要 10 次数据库查询(最初的团队成员是数据库高手,但缺乏像样的算法背景)。
我编写了一个解决方案,将数据库中的 3 个 n 树节点网络转换为一个数据结构,其中每个节点在节点结构数组中存储一次,并且使用其中的双链接指针将 n 树关系转换为三个二叉树阵列,以便可以轻松地在任一方向追踪网络。
它至少快了两个数量级,其中三个数量级是在很长的下游轨迹上。
可悲的是,我实际上不得不向其他几位接受过数据库和 VB 培训的程序员教授一门关于 n 树、二叉树、指针和双向链表的课程,以便让他们理解算法。
At one job I was assigned the task of improving our electrical distribution model's network tracing algorithm as the one they were using was too slow. The 3-phase network was essentially three n-trees (since loops aren't allowed in electrical networks). The network nodes were in the database and some of the original team couldn't figure out how to build an in-memory model so the tracing was done by successive depth SELECTs on the database, filtering on each phase. So to trace a node ten nodes from the substation would require at least 10 database queries (the original team members were database whizzes, but lacked a decent background in algorithms).
I wrote a solution that transformed the 3 n-tree networks of nodes from the database into a data structure where each node was stored once in a node structure array and the n-tree relationship was converted to three binary trees using doubly-linked pointers within the array so that the network could be easily traced in either direction.
It was at least two orders of magnitude faster, three on really long downstream traces.
The sad thing was that I had to practically teach a class in n-trees, binary trees, pointers, and doubly-linked lists to several of the other programmers who had been trained on databases and VB in order for them to understand the algorithms.
这是“如何”和“什么”之间的经典二分法。 你的同学正在研究“如何”编程软件,他们非常关注近焦; 从这个角度来看,从实现的角度来看,了解诸如停止状态和图灵机之类的事情似乎并不重要。
然而,“如何”在计算机科学中所涉及的实际工作却很少。 事实上,我认识的大多数成功的工程师可能认为它只占实际工作的 20% 以下。 到目前为止,“做什么”更为重要。 为此,计算机科学的基础知识至关重要。 你想要做什么更多地与设计有关,而不是与实施有关; 好的设计是……好吧,我们就称其为“不平凡”吧。
“构建软件设计有两种方法:一种方法是使其简单到明显没有缺陷,另一种方法是使其复杂到不存在明显缺陷。第一种方法要困难得多。” - CAR Hoare
祝你学习顺利!
It's a classic dichotomy, between "how" and "what". Your classmates are looking at "how" to program software, and they're very focused on the near focus; from that perspective, the perspective of implementation, it seems like knowing things like halting states and Turing machines are unimportant.
"How" is very little of the actual work that you get expected to do with Computer Science, though. In fact, most successful engineers I know would probably put it at less than 20 percent of the actual job. "What" to do is by far more important; and for that, the fundamentals of Computer Science are critical. "What" you want to do relates much more to design than implementation; and good design is... well, let's just call it "non-trivial".
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
Good luck with your studies!
我认为理解计算的基本模型是有用的:当然,在实践中你永远不需要能够将图灵机转换为寄存器机,但是学习如何看到两个截然不同的问题实际上是同一概念的实例是至关重要的技能。
I think understanding the fundamental models of computation is useful: sure you never need to be able to translate a Turing machine into a register machine in practice, but learning how to see that two very different problems are really instances of the same concept is a critical skill.
大多数知识都不是“实用的”,但可以帮助您以无法预料的方式将各个点联系起来,或者为您提供更丰富的词汇来描述更复杂的想法。
Most knowledge is not "practical", but helps you connect dots in ways that you cannot anticipate, or gives you a richer vocabulary for describing more complex ideas.
重要的不是你研究的具体问题,而是你通过研究它们学到的原理。 我每天在工作中都会使用有关算法、数据结构、编程语言和操作系统的概念。 如果您是一名程序员,您将一直做出影响系统性能的决策。 您需要在基本抽象概念上打下坚实的基础,才能做出正确的选择。
It's not the specific problems that you study that matters, it's the principles that you learn through studying them. I use concepts about algorithms, data structures, programming languages, and operating systems every day at my job. If you work as a programmer you'll make decisions all the time that affect system performance. You need to have a solid foundation in the fundamental abstract concepts in order to make the right choices.
我从CS毕业后我也有类似的想法:我们学的一大堆理论在实践中完全没有用。 这在短时间内被证明是正确的,但是当你处理复杂的任务时,理论绝对比实践更有价值。 每个人经过几年的编码后都可以编写一些“有效”的程序,但并不是每个人都能理解如何工作。 不管怎样,我们大多数人在某个时刻都会处理性能问题、网络延迟、精度、可扩展性等。在这个阶段,理论是至关重要的。 为了在处理复杂系统时设计一个好的解决方案,了解内存管理的工作原理、进程和线程的概念、如何为它们分配内存或提高性能的高效数据结构等非常重要。
例如,有一次我正在开发一个包含大量数学计算的项目,但在某个时候我们的软件失败了。 在调试时,我发现经过一些数学运算后,我收到了一个值为 1.000000000002 的 DOUBLE 数字,但从数学角度来看不能 > 1 在程序的后期阶段给出了传奇的 NaN 异常。 我花了一些时间来解决这个问题,但如果我更多地关注“双精度和浮点数的近似”课程,我就不会浪费时间。
After i graduated from CS I thought similarly: the whole bunch of theories that we studied are completely useless in practice. This proved to be right for a short period of time, however the moment you deal with complex tasks, theory is definitely MORE VALUABLE than practice. every one after few years of coding can write some programs that "work" but not every one is able to understand how. no matter what most of us will deal at a certain point with performance issues, network delays, precission, scalability etc. At this stage the theory is critical. in order to design a good solution when dealing with complex systems is very important to know how the memory management works, the concepts of process and threads, how memory is assigned to them, or efficient data structures for performance and so on.
One time for example i was working on a project including plenty of mathematical calculations and at a certain point our software failed. while debugging i figured out that after some mathematical operation i received a number as DOUBLE of a value 1.000000000002 but from the mathematical perspective couldnt be > 1 which at some later stage in the program was giving the legendary NaN exception. i spent some time to figure this out but if i had paid more attention to the "approximation of Double and Float" lesson i would have not wasted that time.
如果您在一家从事开创性工作的公司工作,那么能够向架构师和开发人员传达其好处是什么就很重要。 各种技术都有很多炒作,给自己定位可能很困难。 当您用科学和理论术语来构建您的创新时,您绝对具有优势,并且客户会感觉到您是真实的。 我可以告诉人们:有一种新的方法来处理状态、编码和不确定性(即复杂性),并且您绝对可以比今天更有效率。
如果你在职业生涯中放眼长远,学习理论会给你带来深度,你需要成长的深度。 学习第五种或第六种编程语言的投资回报将比学习第二种和第三种编程语言少很多。 接触理论将使您对真正的工程有所了解,了解自由度在哪里以及如何做出正确的权衡。
重要概念 1) 状态,2) 编码,3) 非确定性。 如果你不认识他们,他们不会帮助你。 理论应该为你提供的是大局观以及基本概念如何组合在一起的感觉。 它应该可以帮助你磨练你的直觉。
示例:上面的一些答案提到了停机问题和图灵机。 当我在大学里看到图灵的论文时,我并没有感到任何启发。 有一天,我偶然发现了哥德尔不完备定理,尤其是哥德尔数。 事情开始变得有意义了。 多年后,我在一家书店读到了关于格奥尔格·康托的文章。 现在我真正开始理解图灵机和停机问题。 亲自尝试并在维基百科上查找“康托尔对角线论证”。 这是你在智力上遇到过的最棒的事情之一。
深思:典型的图灵机并不是设计状态转换机的唯一方法。 拥有两盘而不是一盘磁带的图灵机可以为许多算法提供更快的速度。 http://www.math.ucla.edu/~ynm/papers/ eng.ps
通过阅读这本书,你可以比我更有效地了解这些见解。 链接在这篇文章的底部。 (至少,请查看亚马逊上的目录,了解这本书的全部内容):
我发现罗森伯格的这本书非常精彩。 http://www.amazon.com/The-Pillars-Computation-Theory-Nondeterminism/ dp/0387096388 如果你只有一本理论书,恕我直言,这应该是一本。
If you work in a company that does groundbreaking work, it is important to be able to communicate to architects and developers what the benefits are. There is a lot of hype about all kinds of technologies and positioning yourself can be difficult. When you frame your innovation in scientific and theoretical terms you are definitely at an advantage and customers sense you are the real thing. I can tell folks: there is a new way to deal with state, encoding and nondeterminism (i.e. complexities) and you can definitely be more productive than you are today.
If you take the long view in your career learning about theory will give you depth, the depth you need to grow. The return on investment in learning your 5th or 6th programming language will be a lot less then learning your 2nd and 3rd. Exposure to theory will give you a sense for real engineering, about where the degrees of freedom are and how you can make the right trade-offs.
The important concepts 1) State, 2) Encoding, 3) Nondeterminism. If you don't know them they will not help you. What theory should provide you with is the big picture and a sense of how basic concepts fit together. It should help you hone your intuition.
Example: some of the answers above mention the halting problem and Turing machines. When I came across Turing's paper in college I did not feel enlightened at all. One day I came across Goedel's incompleteness theorem and Goedel numbering in particular. Things started to make a lot of sense. Years later I read about Georg Cantor at a bookstore. Now I really started to understand Turing machines and the halting problem. Try for yourself and look up "Cantor's Diagonal Argument" on Wikipedia. It is one of the most awesome things intellectually you will ever encounter.
Food for thought: A typical Turing machine is not the only way to design a state transition machine. A Turing machine with two rather than one tape would give you a lot more speed for a number of algorithms. http://www.math.ucla.edu/~ynm/papers/eng.ps
You can expose yourself to these insights more efficiently then I did by reading this book. Link at the bottom of this post. (At the very least, check out the table of contents on Amazon to get a taste of what this is all about):
I found the book by Rosenberg sensational. http://www.amazon.com/The-Pillars-Computation-Theory-Nondeterminism/dp/0387096388 If you have only one book on theory IMHO this should be the one.
我不会每天使用它。 但它给了我很多理解,对我每天都有帮助。
I do not use it on a daily basis. But it gave me a lot of understanding that helps me each day.
我发现我每天在CS理论世界的幸福只需要一句“低耦合、高内聚”的口头禅。 Roger S. Pressman 在Steve McConnell 让它变得时尚。
I found that all I need for daily bliss from the CS theoretical world is the utterance of the mantra "Low coupling and High Cohesion". Roger S. Pressman made it scholarly before Steve McConnell made it fashionable.
是的,我通常使用状态图来设计程序的形状和流程。
一旦理论上可行,我就开始编码和测试,边检查状态边进行。
我发现它们也是向其他人解释流程行为的有用工具。
Ya, I generally use state diagrams to design the shape and flow of the program.
Once it works in theory, I start coding and testing, checking off the states as i go.
I find that they are also a useful tool to explain the behavior of a process to other people.
简单的。 例如:如果我正在使用 RSACryptoServiceProvider,我想知道那是什么以及为什么我可以信任它。
Simple. For example: if I'm using RSACryptoServiceProvider I'd like to know what is that and why I can trust it.
因为 C++ 模板实际上是某种 lambda 演算。 请参阅 www.cs.nott.ac.uk/types06/slides/michelbrink_types_06.pdf
Because C++ templates are actually some kind of lambda calculus. See www.cs.nott.ac.uk/types06/slides/michelbrink_types_06.pdf
我现在正在学习分布式算法课程。 有一个关于容错的章节,它包含一些关于有多少进程可以失败(或行为不当)的上限的证明,以便分布式算法可以正确处理它。
对于许多问题,行为不当的进程最多可达进程总数的三分之一。 在我看来,这非常有用,因为您知道尝试开发更好的算法(在给定的假设下)是毫无意义的。
I'm studying for my Distributed algorithms course now. There is a chapter about fault tolerance and it contains some proofs on the upper bound for how many processes can fail (or misbehave) so that the distributed algorithm can handle it correctly.
For many problems, the bound for misbehaving processes is up to one third of total number of processes. This is quite useful in my opinion because you know that it's pointless to try to develop a better algorithm (under given assumptions).
即使理论课程不会直接使用,它也可能会帮助你更好地思考某些事情。
正如杰弗里·L·惠特利奇所说,你不知道老板会要求你做什么,你可能不得不使用一些你认为没有好处的东西。
Even if theoretical courses aren't going to be used directly, it might help you think better of something.
You don't know what your boss is going to ask you to do, you may have to use something that you thought it won't be benefical, as Jeffrey L Whitledge said.
说实话,我不太同意这里的很多答案。 我编写了我的第一个编译器(为了好玩;我真的有太多的咖啡/空闲时间),而没有上过编译器课程; 基本上我只是扫描了另一个编译器的代码并遵循了模式。 我可以随心所欲地用 C 语言编写一个解析器,但如果我的生活依赖于它,我想我不记得如何绘制下推自动机。
当我决定将类型推断放入我的玩具(命令式)编程语言中时,我首先查看了大约五篇论文,盯着一种叫做“类型化 lambda 演算”的东西............**** ....? 起初,我尝试用“通用变量”和“非通用变量”来实现一些东西,但不知道发生了什么。 然后我放弃了这一切,拿着笔记本坐在那儿,思考如何在支持我需要的所有东西(子类型、一流函数、参数化类型等)的情况下实际实现它,经过几天的思考& 在编写测试程序时,我花费了一个多星期的时间试图弄清楚理论上的废话,结果却大吃一惊。
事实证明,了解计算基础知识(即虚拟内存如何工作、文件系统如何工作、线程/调度、SMP、数据结构)都非常有用。 复杂性理论和 Big-O 的东西有时被证明是有用的(特别是对于 RDBMS 设计之类的事情有用)。 停机问题和自动机/图灵机理论? 绝不。
To be honest, I sort of disagree with a lot of the answers here. I wrote my first compiler (for fun; I really have too much coffee/free time) without having taken a course in compilers; basically I just scanned the code for another compiler and followed the pattern. I could write a parser in C off the top of my head, but I don't think I could remember how to draw a pushdown automaton if my life depended on it.
When I decided I wanted to put type inference in my toy (imperative) programming language, I first looked over probably five papers, staring at something called "typed lambda calculus" going what.... the.... ****....? At first I tried implementing something with "generic variables" and "nongeneric variables" and had no idea what was going on. Then I scrapped it all, and sat there with a notebook figuring out how I could implement it practically with support for all the things I needed (sub-typing, first-class functions, parameterized types, etc.) With a couple days of thinking & writing test programs, I blew away more than a weeks worth of trying to figure out the theoretical crap.
Knowing the basics of computing (i.e. how virtual memory works, how filesystems work, threading/scheduling, SMP, data structures) have all proved HIGHLY useful. Complexity theory and Big-O stuff has sometimes proved useful (especially useful for things like RDBMS design). The halting problem and automata/Turing Machine theory? Never.
我知道这已经过时了,但我对那些声称理论“无用”并且没有理论就可以实践自己的职业的人的简短答复是:
没有基础理论,就没有没有练习。
理论是构建其他事物的基础。 当理论被应用时,实践就是结果。
考虑今天的计算机。今天的普通计算机是在图灵机之上建模和构建的,为了简单起见,图灵机是一个用于计算的抽象/理论模型。 这个理论模型是计算的基础,我们今天使用的所有计算设备,从高端服务器到袖珍电话,都能正常工作,因为底层基础是健全的。
考虑算法分析。简单来说,算法分析和时间复杂度理论已用于对问题进行分类(例如 P、NP、EXP 等),以及我们在尝试解决问题时算法的行为方式。解决不同班级的不同问题。
假设您的一个朋友在某个地方 X 找到了工作,在那里,经理提出了一些简单的要求,例如以下示例:
认为该理论“无用”的你的朋友没有意识到他们刚刚遇到了旅行商问题 (TSP),并且不假思索地开始设计这个系统,结果却发现他们天真的尝试检查所有< /em> 正如最初所要求的,这种可能性是如此之慢,以至于他们的系统无法用于任何实际目的。
事实上,他们不知道为什么系统在检查 5 个城市时运行在“可接受”的水平,但在检查 10 个城市时变得非常慢,而在检查到 40 个城市时就冻结了。 他们的理由是“仅比 5 个城市测试多 2 倍和 8 倍的城市”,并想知道为什么该计划不简单地分别需要“多 2 倍和 8 倍的时间”……
理解这一理论就会让他们至少一眼就能认识到以下内容:
这些数字不言而喻:
他们本可以一开始就意识到他们的系统不会按照他们想象的那样工作。 在为该项目分配了大量时间、精力和其他资源并最终浪费在该项目上之后,该系统后来被认为不切实际并被取消,而这一切都是因为认为“理论毫无用处”。
因此,在这次失败之后,经理们认为“好吧,也许这个系统被低估了;毕竟,我们国家有很多城市,而我们的计算机根本没有我们需要的那么快,因为我们最近取消了系统已经成功”。
管理团队将项目失败的原因归咎于计算机速度慢。 毕竟,他们不是计算机科学理论专家,也没有必要成为专家,而那些本应是该主题专家并且本可以通知他们的人却没有。
但他们还有另一个项目。 其实是一个更简单的。 一周后他们来询问以下内容:
你亲爱的朋友再次接受挑战并立即开始工作。 经过几周的工作,没有任何结果,你的朋友压力很大,不知道该怎么办。 又是一次失败……您的朋友现在因为无法解决这个“简单的问题”而感到“愚蠢”……毕竟,请求本身听起来很简单。
不幸的是,你的朋友虽然坚持认为“理论是无用的”,但没有意识到这个看似简单的请求实际上是一个关于可判定性的棘手问题(即停止问题本身),并且没有已知的解决方案。 这是一项不可能完成的任务。
因此,即使开始努力解决该特定问题也是一个可以避免和预防的错误。 如果有理论框架来理解所请求的内容,他们就可以提出一个不同的、可实现的解决方案......例如实现一个可以简单地杀死的监控进程-SIGTERM任何用户进程(根据用户列表),在某些假设下(例如我们知道每个程序运行应该在 10 分钟内终止,因此任何运行超过 20 分钟的实例都应该被
杀死
)。总之,没有理论的实践就像没有地基的建筑。 迟早,从直角施加适量的压力会使它自行塌陷。 没有例外。
是的,但不是直接。 相反,我们间接依赖它。 这里需要注意的是,不同的理论概念或多或少适用,具体取决于您正在处理的问题领域。
当然,我们:
这是一个事实,简单使用的人 一架飞机旅行不需要理解甚至允许飞机被建造并飞行的理论......但是当有人期望建造所说的机器并让它们工作时...你真的能指望一个连飞行原理都不懂的人能得到好的结果吗?
在历史的大部分时间里,直到莱特兄弟理解了某些关于飞行的理论概念并设法将其付诸实践之前,没有人能够制造出一架飞行器(有些人甚至在测试中死去),这真的是巧合吗?
这并非巧合。 今天我们拥有许多可用的技术,因为建造它们的人首先理解并应用了使它们能够工作的理论原理。
I know this is old, but my short reply to those who claim that theory is 'useless' and that they can practice their profession without it is this:
Without the underlying theory, there is no practice.
Theory is the underlying foundation on top of which other things are built. When theory is applied, practice is the result.
Consider computers today. The common computer today is modeled and built on top of the Turing Machine, which, to keep it simple, is an abstract/theoretical model for computation. This theoretical model lies at the foundation of computing, and all the computing devices we use today, from high-end servers to pocket phones, work because the underlying foundation is sound.
Consider algorithm analysis. In simple terms, algorithm analysis and time-complexity theory have been used to classify problems (e.g. P, NP, EXP, etc) as well as how the algorithms we have behave when trying to solve different problems in different classes.
Suppose one of your friends gets a job at some place X and, while there, a manager makes a few simple requests, such as these examples:
Thinking the theory is 'useless' your friends don't realize that they've just been given the Traveling Salesman Problem (TSP) and start designing this system without a second thought, only to discover their naive attempt to check all the possibilities, as originally requested, is so slow their system is unusable for any practical purposes.
In fact, they have no idea why the system works at an "acceptable" level when checking 5 cities, yet becomes very slow at 10 cities, and just freezes when going up to only 40 cities. They reason that it's only "2x and 8x more cities than the 5 city test" and wonder why the program does not simply require "2x and 8x more time" respectively...
Understanding the theory would've allowed them to realize the following, at least at a glance:
The numbers speak for themselves:
They could've realized at the outset that their system was not going to work as they imagined it would. The system was later considered impractical and cancelled after a significant amount of time, effort, and other resources had been allocated to, and ultimately wasted on, the project --and all because thought "theory is useless".
So after this failure, the managers think "Well, maybe that system was underestimated; after all, there're a LOT of cities in our country and our computers are simply not as fast as we need them to be for our recently cancelled system to have been a success".
The management team blames slow computers as the cause of the project's failure. After all, they're not experts in CS theory, don't need to be, and those who're supposed to be the experts on the topic and could've informed them, didn't.
But they have another project in mind. A simpler one actually. They come the week later and ask say the following:
Your dear friend accepts the challenge again and goes to work immediately. After several weeks of work, there're no results, your friend is stressed, and doesn't know what to do. Yet another failure... your friend now feels "dumb" for not having been able to solve this "simple problem"... after all, the request itself made it sound simple.
Unfortunately, your friend, while insisting that "theory is useless" didn't realize that the, allegedly simple, request was actually an intractable problem about decidability (i.e. the halting problem itself), and that there was no known solution for it. It was an impossible task.
Therefore, even starting work to solve that particular problem was an avoidable and preventable mistake. Had the theoretical framework to understand what was being requested been in place, they could've just proposed a different, and achievable, solution... such as implementing a monitoring process that can simply
kill -SIGTERM <id>
of any user process (as per a list of users) that monopolizes the CPU for some arbitrary/reasonable interval under certain assumptions (e.g. we know every program run should've terminated within 10 minutes, so any instance running for 20+ minutes should bekill
ed).In conclusion, practice without the theory is like a building without a foundation. Sooner or later, the right amount of pressure from the right angle will make it collapse in on itself. No exceptions.
Yes, but not directly. Rather, we rely on it indirectly. The caveat here is that different theoretical concepts will be more or less applicable depending on the problem domain you happen to be working on.
Surely, we:
It's a fact that someone who simply use a plane to travel doesn't need to understand the theory that even allowed planes to be built and fly in the first place... but when someone is expected to build said machines and make them work... can you really expect a good outcome from someone who doesn't understand even the principles of flight?
Was it really a coincidence that, for most of history, no one was able to build a flying machine (and a few even died testing theirs) until the Wright brothers understood certain theoretical concepts about flight and managed to put them into practice?
It's no coincidence. We have a lot of working technology today because the people who built them understood, and applied, the theoretical principles that allowed them to work in the first place.
我想这取决于你进入哪个领域。
I guess it depends on which field you go into.