自编如何选股 知乎公式需要什么编程语言知乎

利益相关:四年211学校软件学院学生,四年的软件公司开发经验。&br&&br&这八年觉得入了好几次门,但是现在是不是入门我也不知道了。&br&第一个月:学会了C语言写了个简单的加减法计算器,觉得我入门了。&br&第一年:写了个支持四则运算,括号,开方,字母运算的计算器。学习过程中自动领悟了模块化,觉得进入了一个新天地,觉得我入门了。&br&第二年:和舍友合作,做了个魔兽主题的俄罗斯方块,有动画声效。体验了多人合作,代码管理,高层设计,模块测试,觉得我入门了。&br&第三年:做了个和同学合作,做了个搜索引擎,有索引算法,网站,网页,搜到了H网站,觉得百度也就这样了,我一定入门了。&br&第四年:做了个基于Java web,数据库的房产管理系统,管理软件也不过如此嘛,觉得我入门了。&br&&br&------------------毕业工作的分隔线--------------------------&br&&br&工作一个月:用了一天的时间自学了JavaScript,html,发现自学一门新技术也就这样了,这一定是入门的征兆。&br&工作第二个月:开始接触公司里面的一个10W行级别的软件,发现直接绕晕,无法理解。觉得自己有点虚。&br&工作第六个月:突然顿悟如何在一个陌生的中型项目(10w级别)工作。当时感觉这就是入门吧。&br&工作一年零六个月:带领两个校招的毕业生,负责了一个3W行左右的小型项目,做的不错,老板还给精神+物质嘉奖了,觉得做一个leader可能就是这样吧,入门一定是这个感觉。&br&工作两年:和我们组的leader,一个写了12年代码的资深工程师深入合作,发现难以望其项背啊,突然觉得自己好弱。然后在他的指导下,学习设计,重构,敏捷等等。&br&工作三年:公司有一个新项目,需要研究新技术,派我上了。当时奋战了一个月,研究技术,出了一些成果之后做了原型,老板觉得不错,决定立项开工。头一次独立开荒,并且结果不错,可能这就是真的入门了吧。&br&&br&------------------跳槽的分隔线--------------------------&br&&br&工作四年-现在:跳了个槽,入职当天就开始改代码,修bug了。发现新的项目,新的技术已经不再是障碍了。这是入门吗?&br&新工作三个月:发现这个项目里面有诸多的设计失误,坚信如果初期架构由我来做,一定会更好些。&br&&br&&b&这到底怎么样才算是入门呢?&/b&&br&&br&&br&&b&===============原答案的分隔线============&br&&/b&&br&&br&&br&编辑草稿的时候正好100个赞了,惶恐,知乎的第一个称得上“高票”的答案了。&br&&br&鉴于评论区里面有几位问我算法不好或者不是计算机专业的,适不适合做开发,并且看起来是学生,这里统一回答一下这个问题。&br&数据结构和算法到底有多重要。&b&对于学生来说,很重要。因为如果你这个学不好,能通过大公司的校招可能性微乎其微。&/b&因为公司评价一个学生的素质基本上就是看潜力(你得聪明),能做事(学习扎实),能学好数据结构这两条是缺一不可的。但是工作中我却从来没有直接的写过一个所谓算法或者数据结构,因为大多数的开发工作是应用开发,数据结构大可以用STL之类的库里面的,你自己几乎不可能写一个质量或者效率超过这些库的代码的。&br&&br&专业有多重要。我自己是软件工程专业的,算是科班出身了。我不太好判断非科班会有多少劣势。但是我在公司中见过很多很多非科班的高手,有学生物的,机械的,还有设计的。如果你是非科班的话,自学就很重要了。学什么呢?我凭记忆写一下我大学时候的专业课吧,可能不全,尽量凭记忆写,如果我写了书名号,你可以百度这本书,这就是教材。《计算系统基础》,&b&数据结构与算法,操作系统,面向对象编程&/b&,计算机组成原理,网络技术原理,数据库原理,&b&《代码大全》&/b&,统计数学,离散数学,&b&c++&/b&,软件工程导论,软件设计导论。&br&加粗的地方是我认为比较重要,至少对于校招面试是有帮助的。&br&&br&校招是去大公司还是小公司呢?有人说小公司可以迅速独当一面,成长快,大公司只是螺丝钉。这点我承认。但是根据我的判断,小公司,长得快;大公司,长得高。&br&我第一份工作是大公司。公司名我不说了,大致描述一下吧,国际化上市公司,从公司离职的有去BAT,google,microsoft的,从BAT出来的也有到这家公司的。我在里面就算一个中流选手吧。大公司的一个好处,无法替代的,对于成长很重要的好处,就是你和优秀的人一起工作,见识了成熟的开发方法,见识了大牛是什么样的,见识了复杂的软件是怎么做出来的,这对于一个刚步入工作的人很重要。并且这些在小公司是很难见识到的。并且大公司里面你往往会有一个资深且优秀的Leader进行辅导带领,这点小公司同样很难提供。&br&&br&我的第二份工作是一个创业公司,技术团队十几个人吧。假如我第一份工作就在这里,很可能我的开发路子就会变得很“野”,不正规。这种野路子可能会很快,但是大量的软件工程先驱探索出的正路子才能够帮你走的更远。并且小公司人水平良莠不齐,业务压力也大,能让你跟着一个资深的高手学习的机会和时间也有限。&br&&br&学过打字的都感觉得到,刚开始随心所欲的打字,开始是打的快。但是真正要打的快,打得好,刚开始就得用“别扭”的正规姿势和指法来打。&br&综上,如果你想在软件开发作为职业生涯,第一份工作建议大公司。
利益相关:四年211学校软件学院学生,四年的软件公司开发经验。 这八年觉得入了好几次门,但是现在是不是入门我也不知道了。 第一个月:学会了C语言写了个简单的加减法计算器,觉得我入门了。 第一年:写了个支持四则运算,括号,开方,字母运算的计算器。…
据我的了解,大部分c语言的入门者学不好c语言,都是因为一个心态问题:&br&初学编程,费了偌大的劲,理解了这,理解了那,竟然只是在黑框下打印出了几个数字。&br&&br&我觉得,初学一门编程语言一定要用合适的方式培养兴趣,黑框显然不是一个好方法。&br&&br&所以,我建议在学习c语言的过程中,把系统API什么的也加进去一起学吧,教人写个带界面的程序比教人成天面对控制台程序,效果可能会好很多,因为这让人觉得学习c语言能做事情。&br&&br&我是在学会了windows编程的时候,才对编程产生了很强的兴趣的,说说我当时写的一些小程序,简单但比较好玩,适合培养编程兴趣(代码量依次增大):&br&1、点击,打开一个对话框,问你是猪不?然后告诉他,说不是的会自动关机,让他选吧。要是他点是,就嘲笑他,点不是,就关机吧。&br&&br&2、桌面下雪程序,在冬天大家都期待下雪的时候,做个简单的下雪程序,用到windows几个基本的api就行了,把这个程序发给大家,不懂的人会觉得非常神奇。我曾经发给几个mm,她们貌似都非常喜欢。&br&&br&3、桌面贪吃蛇,就是用桌面图标玩贪吃蛇,当时听说的时候,觉得太有创意了,网上曾风靡一时啊,但是原理其实很简单,如果你把这个演示给你的同学看,他们会把你视为偶像的。&br&&br&4、然后呢,对qq有兴趣的,去看看早期的qq是怎么写的吧,我记得有一篇《qq是怎样练成的》,还有源代码。改编一下,补充内容,甚至可以去参加学校的软件比赛去了,哈哈。&br&&br&写几个好玩的程序以后,相信你就知道该如何学习编程了,要多给自己找乐趣。
据我的了解,大部分c语言的入门者学不好c语言,都是因为一个心态问题: 初学编程,费了偌大的劲,理解了这,理解了那,竟然只是在黑框下打印出了几个数字。 我觉得,初学一门编程语言一定要用合适的方式培养兴趣,黑框显然不是一个好方法。 所以,我建议在…
在我很小、刚接触编程的时候,&br&老师告诉我,让我写下第一个程序 :HelloWorld!&br&当时很疑惑,就问老师:为什么要是&HelloWorld!&?&br&老师是这么回答的:这意味着你的程序有了生命。&br&就在那一瞬间,爱上了编程。&br&很多年后回想起来,觉得是一个很可爱的问题,和一个很可爱的回答。&br&谢谢这个答案。&br&&br&——————萌萌哒分割线————————&br&居然过千赞了..小透明感觉幸福( o??o? )&br&很多人评论里说,第一个程序是其他的balabala,我觉得并不关键。HelloWorld是个人尽皆知的话,而它又恰巧有这么一个温暖的意思,让人爱上它..这就够了,不是吗?&br&希望大家能被它温暖,爱上编程。
在我很小、刚接触编程的时候, 老师告诉我,让我写下第一个程序 :HelloWorld! 当时很疑惑,就问老师:为什么要是"HelloWorld!"? 老师是这么回答的:这意味着你的程序有了生命。 就在那一瞬间,爱上了编程。 很多年后回想起来,觉得是一个很可爱的问题,和…
这个题目下的答案大致分为几种:&br&&ol&&li&Magic。例如 &a data-hash=&c1c892f179f95da8b37a1dcc& href=&///people/c1c892f179f95da8b37a1dcc& class=&member_mention& data-editable=&true& data-title=&@陈硕& data-tip=&p$b$c1c892f179f95da8b37a1dcc& data-hovercard=&p$b$c1c892f179f95da8b37a1dcc&&@陈硕&/a&, &a data-hash=&203b150d2cb5ae40ae2f6& href=&///people/203b150d2cb5ae40ae2f6& class=&member_mention& data-editable=&true& data-title=&@渡子厄& data-tip=&p$b$203b150d2cb5ae40ae2f6& data-hovercard=&p$b$203b150d2cb5ae40ae2f6&&@渡子厄&/a&(半Magic,因为Wolfram Alpha并没给出准确结果)。这个我就不评论了,因为没说是什么方法。&/li&&li&暴力1到10亿,对每个数判断是否素数(或暴力试除,或Miller Rabin)。方法太暴力,最快也不过&img src=&///equation?tex=%5COmega%28n%5Clog+n%29& alt=&\Omega(n\log n)& eeimg=&1&&,其中&img src=&///equation?tex=n& alt=&n& eeimg=&1&&是上界10亿。&/li&&li&筛出所有&img src=&///equation?tex=n& alt=&n& eeimg=&1&&以内的素数然后加起来。有人用Eratosthenes筛(复杂度&img src=&///equation?tex=O%28n+%5Clog+%5Clog+n%29& alt=&O(n \log \log n)& eeimg=&1&&),有人用欧拉筛(最简单的线性筛之一),也有人用Matlab等软件。此方法也极其暴力。因为不超过n的素数有&img src=&///equation?tex=%5CTheta%28%5Cfrac%7Bn%7D%7B%5Clog+n%7D%29& alt=&\Theta(\frac{n}{\log n})& eeimg=&1&&个,所以任何先找出所有素数再加起来的方法(即使使用亚线性的筛法,例如Atkin筛或Wheel筛)都不可能快于这个时间复杂度。&/li&&li&不知所云型。就不点名了。&/li&&li&理论上更优的算法。目前只看到
&a data-hash=&bbd89e058666a& href=&///people/bbd89e058666a& class=&member_mention& data-editable=&true& data-title=&@罗宸& data-tip=&p$b$bbd89e058666a& data-hovercard=&p$b$bbd89e058666a&&@罗宸&/a&。他给出的代码是来自于Project Euler第10题(&a href=&///?target=https%3A//projecteuler.net/problem%3D10& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Summation of primes&i class=&icon-external&&&/i&&/a& )的论坛中Lucy_Hedgehog给出的Python代码的直接翻译,注释也都还在。接下来我就来介绍一下Lucy_Hedgehog给出的这个算法。&/li&&/ol&&b&==========正式回答分割线=============&/b&&br&&br&&br&首先来感受一下这个算法的速度:&br&&div class=&highlight&&&pre&&code class=&language-text&&$ for n in ; do time python Main.py $n; done
&/code&&/pre&&/div&可以看到,即使是python这样的解释型动态语言,算出10亿的结果也不过需要0.5s,算出1000亿也只要15秒,是完虐以上各种暴力方法的。&br&&br&整个算法类似于Wikipedia中给出的求n以内素数个数的算法(&a href=&///?target=https%3A//en.wikipedia.org/wiki/Prime-counting_function%23Algorithms_for_evaluating_.CF.80.28x.29& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Prime-counting function&i class=&icon-external&&&/i&&/a&),感兴趣的也可以去看一下。&br&&br&&b&==========真正的!正式回答分割线 :D =============&/b&&br&&br&&br&定义&img src=&///equation?tex=S%28v%2Cp%29& alt=&S(v,p)& eeimg=&1&&为&img src=&///equation?tex=2& alt=&2& eeimg=&1&&到&img src=&///equation?tex=v& alt=&v& eeimg=&1&&所有整数中,在普通筛法中外层循环筛完&img src=&///equation?tex=p& alt=&p& eeimg=&1&&时仍然幸存的数的和。因此这些数要不本身是素数,要不其最小的素因子也大于&img src=&///equation?tex=p& alt=&p& eeimg=&1&&。因此我们需要求的是&img src=&///equation?tex=S%28n%2C%5Clfloor%5Csqrt+n%5Crfloor%29& alt=&S(n,\lfloor\sqrt n\rfloor)& eeimg=&1&&,其中&img src=&///equation?tex=n& alt=&n& eeimg=&1&&是十亿。&br&&br&为了计算&img src=&///equation?tex=S%28v%2Cp%29& alt=&S(v,p)& eeimg=&1&&,先考虑几个特殊情况&br&&ol&&li&&img src=&///equation?tex=p%5Cle1& alt=&p\le1& eeimg=&1&&。此时所有数都还没有被筛掉,所以&img src=&///equation?tex=S%28v%2Cp%29%3D%5Csum_%7Bi%3D2%7D%5E%7Bv%7Di%3D%5Cfrac%7B%282%2Bv%29%28v-1%29%7D%7B2%7D& alt=&S(v,p)=\sum_{i=2}^{v}i=\frac{(2+v)(v-1)}{2}& eeimg=&1&&&br&&/li&&li&&img src=&///equation?tex=p& alt=&p& eeimg=&1&&不是素数。因为筛法中&img src=&///equation?tex=p& alt=&p& eeimg=&1&&早已被别的数筛掉,所以在这步什么都不会做,所以此时&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29& alt=&S(v,p)=S(v,p-1)& eeimg=&1&&;&/li&&li&&img src=&///equation?tex=p& alt=&p& eeimg=&1&&是素数,但是&img src=&///equation?tex=v%3Cp%5E2& alt=&v&p^2& eeimg=&1&&。因为每个合数都一定有一个不超过其平方根的素因子,如果筛到&img src=&///equation?tex=p& alt=&p& eeimg=&1&&时还没筛掉一个数,那么筛到&img src=&///equation?tex=p-1& alt=&p-1& eeimg=&1&&时这个数也还在。所以此时也有&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29& alt=&S(v,p)=S(v,p-1)& eeimg=&1&&。&/li&&/ol&&br&现在考虑最后一种稍微麻烦些的情况:&img src=&///equation?tex=p& alt=&p& eeimg=&1&&是素数,且&img src=&///equation?tex=p%5E2%5Cle+v& alt=&p^2\le v& eeimg=&1&&。&br&此时,我们要用素数&img src=&///equation?tex=p& alt=&p& eeimg=&1&&去筛掉剩下的那些数中&img src=&///equation?tex=p& alt=&p& eeimg=&1&&的倍数。注意到现在还剩下的合数都没有小于&img src=&///equation?tex=p& alt=&p& eeimg=&1&&的素因子。因此有:&br&&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29-%5Csum_%7B%5Csubstack%7B2%5Cle+k+%5Cle+v%2C%5C%5C+p%5Cmbox%7B%E4%B8%BA%7Dk%5Cmbox%7B%E7%9A%84%E6%9C%80%E5%B0%8F%E7%B4%A0%E5%9B%A0%E5%AD%90%7D%7D%7Dk& alt=&S(v,p)=S(v,p-1)-\sum_{\substack{2\le k \le v,\\ p\mbox{为}k\mbox{的最小素因子}}}k& eeimg=&1&&&br&&br&后面那项中提取公共因子&img src=&///equation?tex=p& alt=&p& eeimg=&1&&,有:&br&&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29-p%5Ctimes%5Csum_%7B%5Csubstack%7B2%5Cle+k+%5Cle+v%2C%5C%5C+p%5Cmbox%7B%E4%B8%BA%7Dk%5Cmbox%7B%E7%9A%84%E6%9C%80%E5%B0%8F%E7%B4%A0%E5%9B%A0%E5%AD%90%7D%7D%7D%5Cfrac%7Bk%7D%7Bp%7D& alt=&S(v,p)=S(v,p-1)-p\times\sum_{\substack{2\le k \le v,\\ p\mbox{为}k\mbox{的最小素因子}}}\frac{k}{p}& eeimg=&1&&&br&&br&因为&img src=&///equation?tex=p& alt=&p& eeimg=&1&&整除&img src=&///equation?tex=k& alt=&k& eeimg=&1&&,稍微变形一下,令&img src=&///equation?tex=t%3D%5Cfrac%7Bk%7D%7Bp%7D& alt=&t=\frac{k}{p}& eeimg=&1&&,有:&br&&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29-p%5Ctimes%5Csum_%7B%5Csubstack%7B2%5Cle+t+%5Cle+%5Clfloor%5Cfrac%7Bv%7D%7Bp%7D%5Crfloor%2C%5C%5C+t%5Cmbox%7B%E7%9A%84%E6%9C%80%E5%B0%8F%E7%B4%A0%E5%9B%A0%E5%AD%90%7D%5Cge+p%7D%7Dt& alt=&S(v,p)=S(v,p-1)-p\times\sum_{\substack{2\le t \le \lfloor\frac{v}{p}\rfloor,\\ t\mbox{的最小素因子}\ge p}}t& eeimg=&1&&&br&&br&注意到一开始提到的&img src=&///equation?tex=S& alt=&S& eeimg=&1&&的定义(“这些数要不本身是素数,要不其最小的素因子也&b&大于(注意!)&/b&&img src=&///equation?tex=p& alt=&p& eeimg=&1&&”),此时&img src=&///equation?tex=p& alt=&p& eeimg=&1&&后面这项可以用&img src=&///equation?tex=S& alt=&S& eeimg=&1&&来表达:&br&&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29-p%5Ctimes%28S%28%5Cleft%5Clfloor%5Cfrac%7Bv%7D%7Bp%7D%5Cright%5Crfloor%2Cp-1%29-%5C%7Bp-1%5Cmbox%7B%E4%BB%A5%E5%86%85%E7%9A%84%E6%89%80%E6%9C%89%E7%B4%A0%E6%95%B0%E5%92%8C%5C%7D%7D%29& alt=&S(v,p)=S(v,p-1)-p\times(S(\left\lfloor\frac{v}{p}\right\rfloor,p-1)-\{p-1\mbox{以内的所有素数和\}})& eeimg=&1&&&br&&br&再用&img src=&///equation?tex=S& alt=&S& eeimg=&1&&替换素数和得到最终表达式:&br&&img src=&///equation?tex=S%28v%2Cp%29%3DS%28v%2Cp-1%29-p%5Ctimes%28S%28%5Cleft%5Clfloor%5Cfrac%7Bv%7D%7Bp%7D%5Cright%5Crfloor%2Cp-1%29-S%28p-1%2Cp-1%29%29& alt=&S(v,p)=S(v,p-1)-p\times(S(\left\lfloor\frac{v}{p}\right\rfloor,p-1)-S(p-1,p-1))& eeimg=&1&&&br&&br&&br&我们最终的结果是&img src=&///equation?tex=S%28n%2C%5Clfloor%5Csqrt+n%5Crfloor%29& alt=&S(n,\lfloor\sqrt n\rfloor)& eeimg=&1&&。计算时可以使用记忆化,也可以直接自底向上动态规划。&br&至于算法的复杂度就留作练习,是低于以上任何一种暴力方法的。&br&&br&希望我讲清楚了。代码我就不放了,自己解决Project Euler 第10题之后可以去论坛里看Lucy_Hedgehog的代码(在论坛第5页)。也可以去看 &a data-hash=&bbd89e058666a& href=&///people/bbd89e058666a& class=&member_mention& data-editable=&true& data-title=&@罗宸& data-tip=&p$b$bbd89e058666a& data-hovercard=&p$b$bbd89e058666a&&@罗宸&/a& 给出的代码。&br&&br&&br&&b&========== 更新:&/b&&br&&a data-hash=&ad0a1e81c1f9c61fe6bd& href=&///people/ad0a1e81c1f9c61fe6bd& class=&member_mention& data-editable=&true& data-title=&@吴昌隆& data-tip=&p$b$ad0a1e81c1f9c61fe6bd& data-hovercard=&p$b$ad0a1e81c1f9c61fe6bd&&@吴昌隆&/a& 在评论中给出一个链接,其中包含一个理论上更优的算法(&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Theoretical Computer Science Stack Exchange&i class=&icon-external&&&/i&&/a&上&a href=&///?target=http%3A///questions/5578/can-merlin-convince-arthur-about-a-certain-sum& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Charles的回答&i class=&icon-external&&&/i&&/a&)。我粗略读了一下,认为理论上是可行的。因为本题中的答案只有&img src=&///equation?tex=O%28%5Cfrac%7Bn%5E2%7D%7B%5Clog+n%7D%29& alt=&O(\frac{n^2}{\log n})& eeimg=&1&&级别,使用中国剩余定理的话也只需要算到&img src=&///equation?tex=O%28%5Clog+n%29& alt=&O(\log n)& eeimg=&1&&级别的素数,因此总复杂度为&img src=&///equation?tex=O%28n%5E%7B1%2F2%2B%5Cepsilon%7D%5Clog+n%29& alt=&O(n^{1/2+\epsilon}\log n)& eeimg=&1&&。&br&粗略读了下其参考文献(J. C. Lagarias and A. M. Odlyzko, &a href=&///?target=http%3A//www.dtc.umn.edu/%7Eodlyzko/doc/arch/analytic.pi.of.x.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Computing &i class=&icon-external&&&/i&&/a&&a href=&///?target=http%3A//www.dtc.umn.edu/%7Eodlyzko/doc/arch/analytic.pi.of.x.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&π(x): An analytic method&i class=&icon-external&&&/i&&/a&, &em&Journal of Algorithms&/em&&strong&8&/strong& (1987), pp. 173-191. )后,我认为这算法不可能像这个答案中的算法一样在十几行代码内实现,仅放出来供感兴趣的朋友去看一下。
这个题目下的答案大致分为几种: Magic。例如 , (半Magic,因为Wolfram Alpha并没给出准确结果)。这个我就不评论了,因为没说是什么方法。暴力1到10亿,对每个数判断是否素数(或暴力试除,或Miller Rabin)。方法太暴力,最快也不过\Omega(…
打个比方,谭浩强的书就是80年代录像厅里放的那种制作粗糙的港台三级片。&br&放到今天根本没法看:画面不清楚、演员丑、要露也没露多少、仅有的剧情更是无趣到家。&br&但不妨碍那个时候的小青年靠它性启蒙,因为实在没别的可看。&br&不过,如果这么一部老片子连续放十几年,甚至在欧美日本高清AV都普及开来的年代里还把它摆在前面当作经典来膜拜,那就别怪眼界已经变开阔的年轻人们嘲笑了。
打个比方,谭浩强的书就是80年代录像厅里放的那种制作粗糙的港台三级片。 放到今天根本没法看:画面不清楚、演员丑、要露也没露多少、仅有的剧情更是无趣到家。 但不妨碍那个时候的小青年靠它性启蒙,因为实在没别的可看。 不过,如果这么一部老片子连续放…
&p&答这道题的基本都是程序员吧?我这个学生物的凑个热闹~&/p&&p&我不会码代码,不过我看过一些绝妙的代码,它们大概长这样:&/p&&img src=&/v2-8a053fc803d9c600b02b_b.png& data-rawwidth=&1203& data-rawheight=&754& class=&origin_image zh-lightbox-thumb& width=&1203& data-original=&/v2-8a053fc803d9c600b02b_r.png&&&p&这是一些叫做“小鼠肝炎病毒”的RNA序列片段,这种病毒(以及许多其他病毒)的遗传序列有一个特性:&/p&&h2&&b&正着编译是一种蛋白,反过来编译是另一种蛋白&/b&&/h2&&p&就好比你的代码写成机器码是0,那么正着编译出来是一个意思,反过来0则是另一个意思……&/p&&p&&b&病毒的遗传序列就是精简到了如此变态的地步……&/b&&/p&&p&各位程序员们,要不要尝试着编一段正反意思不同、且都有意义的编码呢?&/p&&p&以上&/p&&p&Reference:&/p&&p&Zhang X, Liao C, Lai M M, et al. Coronavirus leader RNA regulates and initiates subgenomic mRNA transcription both in trans and in cis.[J]. Journal of Virology, ): .&/p&&p&------------&/p&&p&轮子哥在评论里贴了个链接,是他写的代码,各位可以去围观一下&/p&
答这道题的基本都是程序员吧?我这个学生物的凑个热闹~我不会码代码,不过我看过一些绝妙的代码,它们大概长这样:这是一些叫做“小鼠肝炎病毒”的RNA序列片段,这种病毒(以及许多其他病毒)的遗传序列有一个特性:正着编译是一种蛋白,反过来编译是另一种…
程序猿多数是野生动物,同学你这样去培训班会被训成萌宠的。
程序猿多数是野生动物,同学你这样去培训班会被训成萌宠的。
int memory=0;&br&int happiness=0;&br&int sadness=0;&br&&br&while(alive)&br&{&br& memory++; &br& happiness++;&br& sadness++;&br&}&br&&br&memory=0;&br&happiness=0;&br&sadness=0;&br&&br&
int memory=0; int happiness=0; int sadness=0; while(alive) { memory++; happiness++; sadness++; } memory=0; happiness=0; sadness=0;
&p&其实这个事情也蛮简单,要垄断一个行业,最高明和优雅的方式就是提高入行的门槛。这个套路已经在美帝的医生和法律行业成功实现了。而程序员这个行业门槛始终无法抬高的主要障碍是一个大家天天打交道却又忽视的大佬玩家。&/p&&br&&br&&p&&b&没错!正是微软!&/b&&/p&&br&&p&其实为什么微软总是被业界不待见,重要原因就是这货一直在降低业界的门槛,这伤害到了整个行业每一个人的切身利益,所以很多人对微软恨之入骨。&/p&&p&试想一下,如果没有VS这样的开发套装,Windows这种平民操作系统根本就不支持软件开发,没有wintel联盟搞的这种uefi,bios,每个人必须从引导程序开始自己编译一个Linux发行版本出来,用vim什么的东西敲代码。本科学了四年估计才能正确的编译某几个Linux发行版,能写程序至少要博士毕业,这样一来,就只有从小家里电脑就有Linux的程序员世家才能胜任这种工作了……&/p&&br&&p&-------------------------------------------------------------------------------------------------&/p&&p&所以要怎么做,这已经是明摆着的了:&/p&&p&首先,在行业和社区里面散播如下言论:&/p&&blockquote&用VS会降低你的编程能力,高手都不用IDE的,必须用vim什么的。
Windows根本就不适合开发,有各种各样的问题,只有Linux才是适合开发的环境。
GUI只会劣化程序员,真正的程序员都用命令行。
跟着微软走,路只会越走越窄。
用微软的技术人会傻掉。&/blockquote&&br&&p&然后……&/p&&blockquote&公司采购开发人员电脑只允许采购Mac的,不允许许装Windows。
开发语言一定要选择那种坑多的,例如Java和JavaScript,因为坑多的语言门槛高,要记住那些坑就要花很多时间……
只会C#、VB什么的一律不招,必须会Java/JavaScript和另外一种小众语言,例如lisp、perl、ruby、go什么的。&/blockquote&&br&&p&最后,你看看业界……&/p&&br&&p&====================================================&/p&&p&写在最后:&/p&&p&我这个答案主要以调侃为主,并不说明目前业界正在尝试抬高入行门槛达成世袭垄断,只是给大家另一个看问题的角度,总的来说,软件开发目前仍然是阶层上升的一个通道。&/p&&br&&p&最后,Bill这个人,我觉得还是有情怀的,和乔帮主在车库里面焊电脑不同。这个富二代从哈佛辍学是给IBM的兼容机写BASIC的解释器的。&/p&
其实这个事情也蛮简单,要垄断一个行业,最高明和优雅的方式就是提高入行的门槛。这个套路已经在美帝的医生和法律行业成功实现了。而程序员这个行业门槛始终无法抬高的主要障碍是一个大家天天打交道却又忽视的大佬玩家。 没错!正是微软! 其实为什么微软总…
感谢点赞的各位,这个答案随手写的,因为不怎么负责任开始还是匿名。这两天本想完善一下,却发现这个坑实在太大。评论中有人认为我吹牛顿吹过了,大家看一下,兼听则明。&br&------------------------以下是原答案---------------------------&br&当然是牛顿啊。你们还是不明白牛顿三定律伟大在哪。牛顿当年写了一本书,叫《自然哲学的数学原理》,根本没有『物理』两个字。牛逼顿之前,人类对自然界的认识基本靠推理(或瞎想)和实验,牛逼顿之后,人类开始用数学工具认识自然了。这里所谓的『认识』,牛逼顿之前,是哲学思辨;牛逼顿之后,是抽象建模、计算、实验。有了计算,才有了工程设计,才有了『科学技术』。这一套认识世界的思想直到现在也没有改变过。&br&如果你非从信息科学里找牛顿级别的理论,我觉得能有一战的是香农的信息论。A Mathematical Theory of Communication,后来再版时候改了一个字,&b&The&/b& Mathematical Theory of Communication
感谢点赞的各位,这个答案随手写的,因为不怎么负责任开始还是匿名。这两天本想完善一下,却发现这个坑实在太大。评论中有人认为我吹牛顿吹过了,大家看一下,兼听则明。 ------------------------以下是原答案--------------------------- 当然是牛顿啊。…
这个问题要展开说,要太多篇幅了,这里简单说一下。&br&&br&本人C++用了8年,Java/C#用了7年。也在大型科技公司,中型创业公司待过。现在回头来看,这两个语言分别代表了两种价值观:&br&&ul&&li&Java:快速迭代,需求为先。&/li&&li&C++:精挑细做,性能为先。&/li&&/ul&因此,对于一个公司的&b&&u&中后端架构&/u&&/b&而言,往往是打江山,靠Java。守江山,靠C++。&br&&br&科技和互联网公司的中后端不仅仅包括了响应前端和缓存请求的服务器集群,还包括了数据的存储,分析,推送和可视化等很多模块。绝大多数这些公司其实对于数据系统的性能以及处理规模上需求不高;相反,其主要的商业和盈利模式就是解决用户需求。或者是根据市场变化,快速推出新的功能。在频繁迭代的过程中,开发要保证鲁棒性,不能因为个人的离职,造成开发的停滞。这么分析下来,中后端的编程工具要有特点:&br&&ul&&li&开发周期短,招聘快&/li&&li&灵活,易扩展,程序鲁棒较强&/li&&li&第三方支持丰富&/li&&li&性能够用&/li&&/ul&这四点抛出来:最合适的选择那就是Java了。&br&&br&而绝大多数到达一定规模的科技公司,对于系统架构的编程工具要有:&br&&ul&&li&开发周期中等&/li&&li&性能,资源高效&/li&&li&相对易扩展,灵活&/li&&li&第三方支持丰富&/li&&/ul&满足这个需求的也就只有C++了。&br&&br&Java这几年虽然有一定进步,但是在效能上和C++的差距还是非常明显的。在很多时候,用同样的时间优化Java达到C++接近的计算效能以及内存同一个量级的内存效率,不如拿C++重构核心瓶颈模块来的方便快捷。&br&&br&具体比较数字看这里:&br&&a href=&///?target=http%3A//benchmarksgame.alioth.debian.org/u64q/compare.php%3Flang%3Dgpp%26lang2%3Djava& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&benchmarksgame.alioth.debian.org&/span&&span class=&invisible&&/u64q/compare.php?lang=gpp&lang2=java&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&在几个标准的性能测试中,两个优化后的Java和C++程序在计算速度的差距大概是2-5倍,内存效率大概在3-10倍。想象一下,你的计算集群有几万台服务器,在核心部件上的内存效率如果能提高假如10倍,那么每年可以节省多少成本? 更高效的计算效能,往往也带来了更快的商业迭代,带来更快的利润提升。&br&&br&但是,Java的优势就是在于开发速度快,而且性能往往是够用的,第三方支持非常丰富。这些特点决定了他是原型化(大中型)分布式系统和管理工具的最佳工具(C#同理)。Google的后端结构非常崇尚利用C++,谷歌的三剑客和后续系统无一例外不是拿C++开发。不过,最近发布的Google Dataflow Model就是完全拿Java搭建的。可见很多时候,性能不是一个项目最关键的指标,而是在项目迭代和系统性能之间达到最合理的折衷。&br&&br&最后,简单说两个案例。某大型社交媒体科技公司在前期发展的时候,基本上很多后端都是用Java来搭建的。这几年公司到达一定规模后,开始在很多核心模块(例如说, 最近发布的Gorilla系统)用C++开发。另外,为了加速服务器的运行效率,很多常用业务级别的PHP代码会被直接编译成C++来执行(HipPop项目,不过这个项目最近被HHVM取代了)。C++由于极其出色的资源利用率,将集群的效能提高了许多(没有附加任何硬件成本),为此节省了很多资源。&br&&br&在金融领域,很多对冲基金是做策略为主,因此策略要对频繁变化的市场和法规做改变。因此在这种变化不稳定的场景上,Java是主力语言。另外一方面,很多交易的策略依赖于第三方的统计,流数据处理和机器学习的算法,这些第三方支持在Java上面很完善。另一方面,例如说高频交易的领域,由于策略池相对较小,交易系统有延迟要求,因此C++天然就很强势。假如一个交易策略有交易延迟上的要求(&1毫秒),Java就直接被排除在外了。&br&&br&因此,很多时候并不是语言的特性决定了我们用什么,而是我们处于怎么样的位置(亦或是公司处于一个什么样的阶段)决定了我们只能用什么工具。&br&&br&归根结底,衡量一个程序员的价值,不取决于你会什么语言,而是你解决的问题,撬动了多少资本,或者是解放了多少生产力。&br&&br&与其问:我应该学什么语言?&br&不如问:我想解决什么领域的问题?
这个问题要展开说,要太多篇幅了,这里简单说一下。 本人C++用了8年,Java/C#用了7年。也在大型科技公司,中型创业公司待过。现在回头来看,这两个语言分别代表了两种价值观: Java:快速迭代,需求为先。C++:精挑细做,性能为先。因此,对于一个公司的中…
不敢说自己懂C语言,权当抛砖引玉吧。&br&&br&&b&为什么要学C语言?&/b&&br&&br&在你学习C语言之前,你必须明白C语言是用来干什么的。也许你看了书上的范例代码,浑浑噩噩,印象里好像可以写一个诸如华氏度转摄氏度的东西,或者是给一堆数排个序之类的。总之,语言是用来写程序的。&br&&br&那什么是程序呢?我不知道你对计算机有多少了解,不过我猜想你应该知道,计算机的处理器能够处理一条一条的指令,这些指令对应着不同的对数据的操作。计算机运行一个程序,就是把这些指令和数据加载到内存里面,然后一条一条地执行。&br&&br&我相信你也知道计算机内部全都是用二进制表示信息。在机器中,每一条指令也是用二进制数来表示的。我们很难记住这些数和指令的对应关系,它的表现也不够直观。所以计算机科学家们开始用助记符(比如mov、jmp等)来表示指令。这被称作汇编语言。尽管相比于徒手撸机器码有进步,但是说到底汇编语言也只是很浅的一层抽象。实现一个复杂的功能,也许要写很长的一段代码。更可怕的是,许多汇编代码移植性不好,切换到另一个平台上需要改很多代码。因此开发大型软件很不方便。&br&&br&在C语言出现之前,已经有过许多在汇编语言基础上进一步抽象的高级语言,比如FORTRAN、COBOL等等,而且许多至今都还在某些领域有各自的一席之地。而C的抽象在它出生的那个年代做得恰到好处,既有高级语言的简洁和表达力,又不失贴近底层系统的直接,再加上它与UNIX系系统的密切关系,C在之后许多年里成为了系统编程和软件开发的首选语言。C的代码相比于之前的汇编,在可移植性上已经有了诸多进步,切换到另一个平台的程序,只要那个平台上有C的编译器,不需要修改或者只需要修改少量的代码。我们可以看到在程序语言发展的过程中一个很明确的趋势就是抽象层次愈来愈高,比如后来又出现了号称“一次编写,处处运行”的依靠虚拟机的Java和众多的脚本语言,当然那是后话了。&br&&br&忘说了,在程序语言的发展之路上,还有另一条分叉,函数式语言,典型代表是lisp。它的思维方式同传统的基于指令的语言截然不同,知乎上有大牛说过,函数式语言就是数学,只要数学不过时,函数式编程语言就不会过时。不过在C诞生那个年代呢,由于机器条件所限,函数式编程语言还没有那么得到人们的重视。&br&&br&好了好了,讲历史的部分到此打住,在今日软件项目的实际开发中,C语言所占的比重早已不能和八九十年代同日而语了。之所以还要学C语言呢,就是因为它跟底层有天生的亲近感,C语言的许多特性和“坑”,深挖下去,其实也是计算机体系结构的问题。《C标准库》的作者在书里打趣说,C大概是少数能自我实现标准库的语言了。所以,学C的时候,如果关注点仅仅是语法本身,那还不如python来得亲切。(不过我想说国内大学里有些教C语言的老师恐怕连python是什么都不知道)&br&&br&&b&什么是Hello, world!&/b&&br&&br&大多数初学C语言的人写的第一个程序都是所谓的“Hello, world!”。简言之,就是一个能在屏幕上输出这句话的&b&程序&/b&。这句话的起源是C语言之父(可不是谭浩强哦)Dennis Ritchie和Brain Kernighan的名著《C程序设计语言》。从此以后成为了所有程序设计语言学习者的第一课。&br&&br&题主说自己是软件工程专业的学生,不知道你是哪个学校的。不过在我校呢,软件相比于牛气冲天的土木和建院实在是太渺小了,许多同学甚至是选专业失败被调剂来的。也许你也像他们一样,对所谓的“程序”或者说“软件”,在之前并没有一个明确的概念或者印象。也许你会认为软件是像网易云音乐一样的,或者说是手机上的微信一样的,有一个漂漂亮亮的窗口,还有按钮,还有标签什么的东西。但当你费尽千辛万苦,照着书上敲完这一段也许还不能一次敲对的代码,结果发现只有一个“黑漆漆”的屏幕的时候,你会不会略感失望呢?这就是我要的程序吗,为什么长这样?&br&&br&如果你去问老师,说自己不想要这种程序。脾气不好的老师也许会直接骂你一顿,有耐心点的老师可能会告诉你学会了这个才打好了基础。可是我想你还是不明白这个黑漆漆的窗口到底代表着什么。这也难怪,因为你用的是Windows,如果之前没有弄过什么bat脚本的话,也许都从来没有接触过终端这个东西。不过我想你可以给家里人打个电话聊聊。如果你爸妈在九十年代的时候学过计算机的话,他们应该对DOS的命令行界面还有印象。说不定小时候偷看过亲戚玩电脑的你也有。事实上,在所谓的“图形用户界面”出现以前,一个程序的输入和输出基本只能依靠命令行中的键盘和屏幕。你在Windows的资源管理器里对着a.txt右键点击删除,和你在DOS的黑屏幕里敲del a.txt然后回车是一个效果。只不过,前者可能对用户而言更加友好。&br&&br&所以你明白了吧,由于早期计算机的显示技术和设计理念的限制,输入输出采用的是命令行的方式。而你跑这个Hello, world!程序时候出现的黑窗口,实际上可以理解为是Windows对早期命令行系统的一种&b&模拟&/b&。如果你还知晓有一种语言叫VB,它的Hello, world!可以用创建一个窗体,然后在上面画一个Label的方式来实现。对比一下,可以发现,其实这两者之间并无什么本质区别。之所以我们喜用在命令行下输出Hello, world!的程序来教授编程的第一课,原因首先是它简单,不用考虑输出的布局、格式,仅仅是内容就可以了;然后是C语言的&b&标准库&/b&也并没有给我们提供这样一个图形化的&b&接口&/b&。事实上设计一个图形界面的程序也没有那么简单,你需要设定好布局,要为每个组件编写事件响应接口……作为初学者,你应当知晓的是,之所以用命令行,并不是因为C语言不能做图形界面,而是因为那跟我们在初学的时候需要挖掘的东西相隔太远。不管是写一个命令行的Hello, world!,还是点击按钮弹出Hello, world!,甚至是用电脑的蜂鸣器bee一声,本质都是一样的。&br&&br&&b&编程的意义&/b&&br&&br&事实上,写程序和设计的目的是一样的,都是为了解决问题。(尽管有些人喜欢欣赏所谓“纯粹的技术”)国内高校教材最大的缺点之一,就是只告诉你这个是什么,却从来不告诉你学了有什么用。即使讲了所谓的用途,给人的感觉也只是凑数用的。不信?可以拿我校数学系编的那本紫皮的《线性代数》和国外优秀的线代教材比,看看两者差距有多大。&br&&br&尽管C语言相比python、Java等语言缺少许多必要的“轮子”,不过对于初学者来说,写点能运行剪刀石头布的代码,或者说能够从某个文本文件里读入生词然后考查你背得如何的程序,都可以带来巨大的成就感。上编程课和上高等数学不一样,它不应该有什么进度之分。在了解完基本的语法之后就可以动手实现了,期间遇到什么问题再去网上查。写完了再去跟别人写得好的对比,看自己哪里不足。&br&&br&初学编程,关键在练习。&br&&br&&b&语法有什么用?&/b&&br&&br&似乎谭浩强和其它诸多所谓国内“专家”编写的教材,把C语言当做数学来讲,按照不同的语法内容划分成章节,有些学校说不定最后还会有笔试。有些学校甚至还叫学生上交手抄代码。我不太能够理解和认同这种行为。作为初学编程的你,大概早就受够了这种被动式的接受,在心里反问自己:就算我都看完了,能写出个什么呢?&br&&br&确实写不出什么东西。因为在这种情况下,读者很难理解到这些语法的含义。比如,你看到书上讲分支语句和循环语句的时候,有想过它们有什么用吗?我不用分支行不行,不用循环行不行?&br&&br&试想我们有一个程序,让我们在输入的一堆数里面找出最大的那个。假设输入是定死的,第三个数最大,那我完全可以接收到第三个输入的时候直接输出,结束程序了对不对?你可能觉得我这样是在耍流氓,哪里会有这样的程序。事实上,这也是所谓条件语句存在的本质——程序需要接受不同的输入(任何形式)。如果输入是固定的,那么理论上我可以改写为没有条件语句的代码。变量的概念,也是因为它所包含的值不是确定的。话说回来,只有用if语句才能实现分支结构吗?你让我求一年每个月多少天,我是不是可以开一个数组来保存,然后单独判断闰年就可以了?你让我输出从1到100任意一个整数的平方,理论上我用switch...case语句或者if也能做,可直接输出n*n,不是更好理解也更方便吗?循环其实是类似的道理,只是它的目的在于重复执行某一段代码,而重复次数是不固定的。我们说过,编程的目的是解决问题,不是让你在写代码的时候故意卖弄一些什么东西上去把代码搞乱,像写高中的语文作文一样。&br&&br&每学到某个语法概念的时候,都要问一问自己,如果没有这个东西,有没有什么程序是写不出来的?或者说,如果没有了这个语法,我写程序的时候会增加多少麻烦?理论上,一门编程语言只需要非常简单的语法,就可以写出任何形式的程序。(可以搜一下“图灵完备”)但是为什么还有这么多编程语言呢?为什么有的编程语言适用于某个特定领域呢?为什么人们会觉得用python写点小程序比C要来得方便呢?C语言和现代高级的脚本语言比,语法实在可以用“简陋”来形容,标准库提供的东西也不多,实际编程要用到的一些数据结构都要自己去实现。在自己“造轮子”的过程当中,你会自己去感受诸如内存分配这样的事情,在这个基础上理解其他语言一些高级数据结构的实现原理。比如说链表,比如说内存池。&br&&br&&b&公式和代码的区别&/b&&br&&br&虽然说一开始学习编程的时候,许多同学都会把C语言当做一个计算器来用,比如说我输入一个变量a,然后计算它的一个函数再输出。在这个层面上,我们可以说,如果不考虑溢出的情况,数学公式(或者说理论上的算法吧)和实际代码可能是对等的。这是非常简单的情况。但是当我们的程序越来越大,步骤越来越复杂,写起代码来可能就没那么简单了。比方说,我们用C来写高精度相乘,最简单的情况是两个数组,每个元素代表一位。如果在脑子里想,可能会很简单:就是逐位乘然后相加嘛。可如果你真动手写了,你会面临这样的问题:&br&&ul&&li&既然我的数占不满整个数组,那到底是靠左还是靠右?&/li&&li&乘法的过程不能一次结束,我需要一个临时数组来容纳中间结果吗?&/li&&li&我怎么知道这一轮乘的数是十位、百位,还是千位?相乘的函数应该有几个参数?&/li&&li&如果题目包含小数,我怎么知道最终结果小数点后有多少位?我应该怎么输出?&/li&&li&……&/li&&/ul&尽管在搞竞赛的人看来这简直就是入门都算不上的题,但是还是有很多人不能一次写对的(poj1001,比如我……)。数学上的算法和公式是普适的,但是要实现成程序,就必须要落脚到具体语言的语法上。为什么人们说要学好编程要多练习?因为练习就是一个踩坑的过程。我这一次踩到这个坑了,知道这里容易出错,我总结下来,以后也是如此。天下大事必作于细,所谓的代码能力就是这个。对编程的初学者来说,知道不等于会做。所以如果有什么程序自己老是写不对,不要一下子就灰心丧气,但是要对它有个印象。比如说数组不会自动初始化,比如if不加花括号就只执行后面一句。&br&&br&&b&C语言与底层系统&/b&&br&&br&我们讲,C语言在出生的时候,因为作了适当层次的抽象,才能抓住历史潮流成为最流行的语言之一。这个所谓的“适当层次”,意思就是既避免了直接面向机器指令,又不完全将计算机运行的原理隐藏起来。于是你稍微学深入了,会产生许多疑问……&br&&ul&&li&为什么printf(&%u&, -1);结果会输出?&/li&&li&为什么数组访问a[-1]但程序没有出错?&/li&&li&为什么char str[]=&abcd&;我就可以修改str[0],而对于char *str=&abcd&;我这样做程序就会出错?&/li&&li&为什么我#define G 3+3而G*G的结果却是15?&/li&&li&为什么scanf的参数名要加一个&号?&/li&&li&为什么printf和scanf的参数可以是不固定的?&/li&&li&为什么一个浮点数加了10次0.1之后结果却是0.99999...?&/li&&li&为什么一个局部数组开太大了程序会爆掉?&/li&&li&……&br&多数问题,深挖下去都和计算机体系结构、计算机内部数据表示、可执行文件格式、编译原理等内容相关。知其然而不知其所以然,就很难说自己了解C语言。&/li&&/ul&&br&&b&数据结构&/b&&br&&br&作为一个看见算法就晕的非ACMer,我想我本来没有什么资格说数据结构。不过我想换个角度谈谈这个问题。数据结构和算法的重要性自不必说,太多人都会像一个长者一样叮嘱你要想程序写得好,数据结构最重要。数据结构的确重要。可是你有没有想过,到底什么是数据结构,数据结构的本质是什么?&br&&br&有一大批讲授数据结构的书籍一开始就把各种数据结构的概念灌输给你,然后带着你用实际的代码去实现这些结构(多半是C++或者Java的书吧)。不过我觉得这些作者仍然忽略了一个问题,即:这些东西有什么用?&br&&br&事实上,每种数据结构都可以看作是对现实生活中物件的刻画。为什么会有栈?因为有很多场景需要先进后出。更本质地说,是在这些场景里面,先进的需要包含后进的才能完成。比方说C语言函数的调用栈,逆序表达式的求值。或者在生活当中,假设我们要拆一台电脑,我们得先打开它的外壳,然后拆下大零件,最后弄下大零件里包含的小零件。如果我们要装配回去,我们要先装上小的,再装上大的,这里有一个先后顺序。我们就可以说,当我们拆机的时候,各个零件组成了一个栈,外面的壳在栈底,里面的小部件在栈顶。当然,在修电脑的时候,我完全可以把所有的零件一通乱地扔在我的床上,要装上去的时候再找,不用像数组一样有序排列。为什么?因为当我完成步骤k的时候,我内心清楚k+1步需要哪个零件。而写程序的时候,比如求逆序表达式的值,我就没有办法知道下一个“零件”是什么,我只能猜测是栈顶元素。因此,在实际程序中,它必须有序。这就是栈这种数据结构的来源,它是一种抽象。本质上讲,这也是个信息的问题。&br&&br&其他的数据结构,比如队列、树、哈希表等等,都一样可以看作是对现实生活中事物运转方式的刻画。比如树是一个极其典型的递归结构,想一想中世纪欧洲的封建制度,其原则是“我只需要对我下面一级的人发号施令就行了”。所谓二叉树,它的特殊性在于它是树的最简形式,节点有两个子节点的情况是生活中最常见的,比如我们的四则运算就可以用树来表示。嗯,说到四则运算,我们可以把普通的中序表达式转化为逆序表达式,本质上也就是把一棵二叉树变成了栈,感受一下这个算法。&br&&br&&b&功利一点?&/b&&br&&br&其实如果仅就题主的问题本身,我想我没有必要说那么多。我个人感觉,我校软院对大一新生的C语言考察要求还是不高的(可能是我校太渣?)。期末上机三道题,第一题无脑,第二题要考到C语言里的许多语法内容,第三题会涉及到数据结构,不过不懂的人凭感觉写估计也能过几组数据。所以如果说你的目的仅仅是通过考试拿一个不错的成绩的话,大概没有必要花这么多时间去看这些“有的没的”的东西。后面一些回答提到的东西大概是从从事C开发的专业人士的角度阐述的。作为大一新生,其实你就像我,不知道自己以后会从事哪方面的工作,也许去干前端也说不定。我绝对不相信一个对操作系统没什么了解的大学生真能像某些人建议的一样啃下APUE,更何况一个连C编程和Linux操作都不熟悉的呢,是吧?&br&&br&如果你所在的学校还没有脑残到要笔试学生C语言的程度,并且你们用的教材是谭浩强那本的话,我觉得你可以扔掉它了,真的。谭老对我国计算机普及作出的贡献当然很大。但是都到2015年了,学校还在用这本书,我看这不是谭浩强之耻,是学校之耻!我没有看过C Primer Plus这本书,写作这个回答的时候到学校图书馆翻了翻,感觉还可以。学计算机的话,就不要畏惧这些大部头了。厚不一定代表难读。大学的课堂老师一学期也讲不了多少内容,多数还得自己去看。一个好的老师,只能说给学生以最正面的引导,让他们少走弯路。&br&&br&现在这个时代,大学生可以接触到的项目很多,主要的类型无非是跟Web相关,其中的大多数也用不到C语言。不过不要因此就否定C/C++的价值,对此知乎上的大牛们讲的很多了。&br&&br&还有,千万记住,C和C++是两种语言,C++也不完全兼容C. 不信?在C和C++里分别输出sizeof('Z')试试。&br&&br&&b&建议书目&/b&&br&&br&&i&Code: The Hidden Language of Computer Hardware and Software&/i&&br&&i&The Information: A History, A Theory, A Flood&/i&&br&&i&Head First C&/i&&br&&i&C Programming: A Modern Approach&/i&&br&&i&The C Programming Language&/i&&br&&i&Computer Systems: A Programmer's Perspective&/i&&br&&i&Expert C Programming: Deep C Secrets&/i&&br&&i&Pointers on C&/i&&br&&i&C Traps and Pitfalls&/i&&br&&br&(题主可以看一下鄙人拙作&a href=&///?target=http%3A//www.little-star.wang/collection/cguide.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cguide&i class=&icon-external&&&/i&&/a&)&br&(答主也是大一学生啊喂,有什么表达不准确的欢迎指出,不过请轻喷...)
不敢说自己懂C语言,权当抛砖引玉吧。 为什么要学C语言? 在你学习C语言之前,你必须明白C语言是用来干什么的。也许你看了书上的范例代码,浑浑噩噩,印象里好像可以写一个诸如华氏度转摄氏度的东西,或者是给一堆数排个序之类的。总之,语言是用来写程序的…
在这里回答一下第一个,第二个,第四个和第五个问题。&br&在回答这个问题之前,必须要有一些限定。因为显卡是有很多种,显卡所在平台也很多种,不能一概而论。我的回答都是基于Intel x86平台下的Intel自家的GEN显示核心单元(也就是市面上的HD 4000什么的)。操作系统大多数以Linux为例。&br&&br&&&& Q1. 显卡驱动是怎么控制显卡的, 就是说, 使用那些指令控制显卡, 通过端口么?&br&&br&目前的显卡驱动,不是单纯的一个独立的驱动模块,而是几个驱动模块的集合。用户态和内核态驱动都有。以Linux桌面系统为例,按照模块划分,内核驱动有drm/i915模块, 用户驱动包括libdrm, Xorg的DDX和DIX,3D的LibGL, Video的Libva等等,各个用户态驱动可能相互依赖,相互协作,作用各不相同。限于篇幅无法一一介绍。如果按照功能划分的话,大概分成5大类,display, 2D, 3D, video, 以及General Purpose Computing 通用计算。Display是关于如何显示内容,比如分辨率啊,刷新率啊,多屏显示啊。2D现在用的很少了,基本就是画点画线加速,快速内存拷贝(也就是一种DMA)。3D就复杂了,基本现在2D的事儿也用3D干。3D涉及很多计算机图形学的知识,我的短板,我就不多说了。Video是指硬件加速的视频编解码。通用计算就是对于OpenCL,OpenCV,CUDA这些框架的支持。&br&&br&回到问题,驱动如何控制显卡。&br&首先,操作硬件的动作是敏感动作,一般只有内核才有权限。个别情况会由用户态操作,但是也是通过内核建立寄存器映射才行。&br&理解驱动程序最重要的一句话是,寄存器是软件控制硬件的唯一途径。所以你问如何控制显卡,答案就是靠读写显卡提供的寄存器。&br&通过什么读写呢?据我所知的目前的显卡驱动,基本没有用低效的端口IO的方式读写。现在都是通过MMIO把寄存器映射的内核地址空间,然后用内存访问指令(也就是一般的C语言赋值语句)来访问。具体可以参考”内核内存映射,MMIO“的相关资料。&br&&br&&&&Q2.2. DirectX 或 OpenGL 或 CUDA 或 OpenCL 怎么找到显卡驱动, 显卡驱动是不是要为他们提供接口的实现, 如果是, 那么DirectX和OpenGL和CUDA和OpenCL需要显卡驱动提供的接口都是什么, 这个文档在哪能下载到? 如果不是, 那么DirectX, OpenGL, CL, CUDA是怎么控制显卡的? &br&&br&这个问题我仅仅针对OpenGL和OpenCL在Linux上的实现尝试回答一下。&br&a.关于如何找到驱动?首先这里我们要明确一下驱动程序是什么,对于OpenGL来说,有个用户态的库叫做LibGL.so,这个就是OpenGL的用户态驱动(也可以称之为库,但是一定会另外再依赖一个硬件相关的动态库,这个就是更狭义的驱动),直接对应用程序提供API。同样,OpenCL,也有一个LibCL.so.。这些so文件都依赖下层更底层的用户态驱动作为支持(在Linux下,显卡相关的驱动,一般是一个通用层驱动.so文件提供API,然后下面接一个平台相关的.so文件提供对应的硬件支持。比如LibVA.so提供视频加速的API,i965_video_drv.so是他的后端,提供Intel平台对应libva的硬件加速的实现)。 下面给你一张大图:&br&&img src=&/5cb482f641c952c52efff_b.jpg& data-rawwidth=&1200& data-rawheight=&675& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&/5cb482f641c952c52efff_r.jpg&&如图可见,最上层的用户态驱动向下依赖很多设备相关的驱动,最后回到Libdrm这层,这一层是内核和用户态的临界。一般在这里,想用显卡的程序会open一个/dev/dri/card0的设备节点,这个节点是由显卡内核驱动创建的。当然这个open的动作不是由应用程序直接进行的,通常会使用一些富足函数,比如drmOpenByName, drmOpenByBusID. 在此之前还会有一些查询的操作,查询板卡的名称或者Bus ID。然后调用对应的辅助函数打开设备节点。打开之后,他就可以根据DRI的规范来使用显卡的功能。我说的这一切都是有规范的,在Linux里叫DRI(Direct Rendering Infrastructure)。&br&所有这些图片文档都可以&a href=&///?target=http%3A//en.wikipedia.org/wiki/Direct_Rendering_Infrastructure& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Direct Rendering Infrastructure&i class=&icon-external&&&/i&&/a& 和 freedesktop上的页面DRI wiki找到&a href=&///?target=http%3A//dri.freedesktop.org/wiki/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&DRI Wiki&i class=&icon-external&&&/i&&/a&&br&显卡驱动的结构很复杂,这里有设计原因也有历史原因。&br&b.关于接口的定义,源代码都可以在我上面提供的链接里找到。这一套是规范,有协议的。&br&c.OpenGL, OpenCL或者LibVA之类的需要显卡提供点阵运算,通用计算,或者编解码服务的驱动程序,一般都是通过两种途径操作显卡。第一个是使用DRM提供的ioctl机制,就是系统调用。这类操作一般包括申请释放显存对象,映射显存对象,执行GPU指令等等。另一种是用户态驱动把用户的API语意翻译成为一组GPU指令,然后在内核驱动的帮助下(就是第一种的执行GPU指令的ioctl)把指令下达给GPU做运算。具体细节就不多说了,这些可以通过阅读源代码获得。&br&&br&&&&Q4. 显卡 ( 或其他设备 ) 可以访问内存么? 内存地址映射的原理是什么, 为什么 B8000H 到 C7FFFH 是显存的地址, 向这个地址空间写入数据后, 是直接通过总线写入显存了么, 还是依然写在内存中, 显卡到内存中读取, 如果直接写到显存了, 会出现延时和等待么? &br&&br&a..可以访问内存。如果访问不了,那显示的东西是从哪儿来的呢?你在硬盘的一部A片,总不能自己放到显卡里解码渲染吧?&br&b.显卡访问内存,3种主要方式。&br&第一种,就是framebuffer。CPU搞一块内存名叫Framebuffer,里面放上要显示的东西,显卡有个部件叫DIsplay Controller会扫描那块内存,然后把内容显示到屏幕上。至于具体如何配置成功的,Long story, 这里不细说了。&br&第二种,DMA。DMA懂吧?就是硬件设备直接从内存取数据,当然需要软件先配置,这就是graphics driver的活儿。在显卡驱动里,DMA还有个专用的名字叫Blit。&br&第三种,内存共享。Intel的平台,显存和内存本质都是主存。区别是CPU用的需要MMU映射,GPU用的需要GPU的MMU叫做GTT映射。所以共享内存的方法很简单,把同一个物理页既填到MMU页表里,也填到GTT页表里。具体细节和原理,依照每个人的基础不同,需要看的文档不同。。。&br&c.为什么是那个固定地址?这个地址学名叫做Aperture空间,就是为了吧显存映射到一个段连续的物理空间。为什么要映射,就是为了显卡可以连续访问一段地址。因为内存是分页的,但是硬件经常需要连续的页。其实还有一个更重要的原因是为了解决叫做tiling的关于图形内存存储形势和不同内存不一致的问题(这个太专业了对于一般人来说)。&br&这地址的起始地址是平台相关,PC平台一般由固件(BIOS之流)统筹规划总线地址空间之后为显卡特别划分一块。地址区间的大小一般也可以在固件里指定或者配置。&br&另外,还有一类地址也是高位固定划分的称为stolen memory,这个是x86平台都有的,就是窃取一块物理内存专门为最基本的图形输出使用,比如终端字符显示,framebuffer。起始地址也是固件决定,大小有默认值也可以配置。&br&d. 刚才说了,Intel的显存内存一回事儿。至于独立显卡有独立显存的平台来回答你这个问题是这样的:任何访存都是通过总线的,直接写也是通过总线写,拷贝也是通过总线拷贝;有时候需要先写入临时内存再拷贝一遍到目标区域,原因很多种;写操作都是通过PCI总线都有延迟,写谁都有。总线就是各个设备共享的资源,需要仲裁之类的机制,肯定有时候要等一下。&br&&br&&&&Q5. 以上这些知识从哪些书籍上可以获得?&br&&br&&a href=&///?target=https%3A//01.org/linuxgraphics& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Intel Graphics for Linux*&i class=&icon-external&&&/i&&/a&, 从这里看起吧少年。这类过于专业的知识,不建议在一般经验交流的平台求助,很难得到准确的答案。你这类问题,需要的就是准确答案。不然会把本来就不容易理解的问题变得更复杂。
在这里回答一下第一个,第二个,第四个和第五个问题。 在回答这个问题之前,必须要有一些限定。因为显卡是有很多种,显卡所在平台也很多种,不能一概而论。我的回答都是基于Intel x86平台下的Intel自家的GEN显示核心单元(也就是市面上的HD 4000什么的)。…
讲一个效果很震撼的&br&现在的机器人运动控制,基本上都是针对某一个或某一类动作进行设计,以仿人机器人为例,一个踢球动作就有上百上千篇学术论文在研究。&br&而人工智能机器学习这些,在实际机器人运动控制、规划中的使用还基本上局限于学习个模型参数程度的水平。&br&用算法根据环境和机器人状态自动生成动作?似乎还很遥远。&br&直到我看到这个研究:&br&CONTACT-INVARIANT TRAJECTORY OPTIMIZATION&br&一句话,对于任意结构的机器人,任意初始姿态位置,只要指定了末状态,算法可以自动生成符合物理规律的,机器人全身动作。&br&不只是走两步,站起来这么简单,甚至有爬楼梯、倒立、两人配合攀登等等。。&br&&img src=&/57eed0a5b4_b.jpg& data-rawwidth=&281& data-rawheight=&256& class=&content_image& width=&281&&&img src=&/51c84c4c092fef0a3155bd6adf0c4907_b.jpg& data-rawwidth=&241& data-rawheight=&267& class=&content_image& width=&241&&&br&看视频更直观:&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/highlight/MordatchSIGGRAPH12.mp4& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/highlight/MordatchSIGGRAPH12.mp4&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&甚至转笔这种动作:&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/highlight/MordatchSCA12.mp4& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/highlight/MordatchSCA12.mp4&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&img src=&/16da2a8a59a00d9ded567_b.jpg& data-rawwidth=&319& data-rawheight=&225& class=&content_image& width=&319&&&br&这个教授的主页&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Emo Todorov&i class=&icon-external&&&/i&&/a& 保加利亚人,高中是数学和信息的双料国际金牌。。。&br&&br&想听原理的话,简单说来,用轨迹优化,特殊之处是用加附加变量的方式把各个接触面的接触情况也编码进整个模型的“状态”里,并使用“软化” 的接触动力学模型,把运动规划这个本来包含很多不连续处(比如撞击,其实任何接触面的变化都意味着系统动力学特性的突变)的问题表述成一个连续、无约束的凸优化问题。详情去看论文。&br&&br&虽然严格说来算法对实际环境做了不少假设和简化,但它解决的问题还是非常有价值,给人以启发的。&br&&br&/***************更新***************/&br&1. 感谢许多知友的提醒,这个其实不算控制算法,属于运动规划算法。算法得到的轨迹往机器人身上用的时候,需要的是控制算法来聪明地利用反馈信息,既实现动作又维持机器人平衡等要求。&br&2. 该实验室在此项目上正在做的就是做实时控制器。已经发表的成果是通过同时对多个不同的模型进行轨迹优化,提高轨迹的鲁棒性(想法是,如果一条轨迹在仿真中对10个质量分布略不同的机器人都能稳定,那实际的机器人应当处于这10个情况中间的某处,也稳定),在线跑时用一个简单的线性反馈控制器。实现了DARwIn上幅度很大的动作,比如一步转身90度之类。论文连接:&br&&a href=&///?target=http%3A//homes.cs.washington.edu/%7Etodorov/papers/MordatchICRA15.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&homes.cs.washington.edu&/span&&span class=&invisible&&/~todorov/papers/MordatchICRA15.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&3. 我微信在写机器人新闻,手动翻译国外最新消息,懒得看英文新闻又对机器人行业感兴趣的童鞋欢迎关注:微信号GoRobotics&br&&p&&a href=&///?target=http%3A///r/vUz-55jESMU3rdyE9xmv& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/r/vUz-55j&/span&&span class=&invisible&&ESMU3rdyE9xmv&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& (二维码自动识别)&/p&
讲一个效果很震撼的 现在的机器人运动控制,基本上都是针对某一个或某一类动作进行设计,以仿人机器人为例,一个踢球动作就有上百上千篇学术论文在研究。 而人工智能机器学习这些,在实际机器人运动控制、规划中的使用还基本上局限于学习个模型参数程度的水…
&p&谁说C不适合入门?只不过你我对入门的定义未必相同。&/p&&br&&p&想知道什么语言适合不适合“入门”,你起码得拿出地图看看人家所谓的“门”在哪里、并且有能力对比多条路线,这才有资格说哪条路线更好入门,对吧?&/p&&p&比如说,如果两个人的目标分别是:
1、&b&其实我什么都不想知道。妈蛋随便来个什么把任务凑出来啊啊啊啊啊啊啊&/b&
对他来说,可能搜索引擎才是最好的“编程语言”。&/p&&p&只是……写程序的那些懒蛋太不努力,不肯把任何东西都实现好白送给人家,人家既不想写又不想掏钱实在很难办……&/p&&p&所以,没办法,找个啥都不用知道,能“很容易的找到很多半成品”然后很容易就能把半成品们凑合到一起得到差不多满足需要的编程语言就算了——哎呀没有?那就给个尽量简单的,能少学点就少学点。&/p&&br&&p&PS:其实这种最好是学linux。因为哪种语言都很难和linux比工具强大丰富……什么awk sed等等,玩转了绝对是另一个天地,哪需要学什么编程。
就是很多编程语言,也从linux的这些东西上收益匪浅,尤其是php/perl之类,离开linux简直是瘸了两条半腿有木有……
&a href=&///?target=http%3A///articles/8883.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&应该知道的Linux技巧&i class=&icon-external&&&/i&&/a& &a href=&///?target=http%3A///articles/9070.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AWK 简明教程&i class=&icon-external&&&/i&&/a& ——尤其推荐这个。看看什么叫awk黑科技……&/p&&p&当然,大家都知道,他们是绝不会离开温暖的windows的——别说硬着头皮尝试linux了;就是学python之类简单的脚本语言,都要挑肥拣瘦“有所学有所不学”的。&/p&&br&&p&2、&b&我想要彻底学会编程,解决一切可以用计算机解决的问题&/b&
嗯,你居然给推荐个一拖一放就能自动生成极为酷炫软件的……类似游戏地图编辑器的玩具?&/p&&p&是,真快。啥都不用看,两天就搞出个“酷炫”的垃圾了;可学了两年拖放,还是只能写“酷炫”的垃圾?
为什么别人学了半年就能写“外部命令”给这个“酷炫”的东西扩展功能,而我却只能张嘴等人喂?人家一张嘴一串术语我连子程序是什么都不知道你确定真不是坑我?
傻瓜式封装啊你听听,你这是想让我当一辈子傻瓜是吧?&/p&&p&所以你看,想走这个方向,反而极为排斥那些“酷炫”、“便利”的东西,因为太容易被引偏方向了——所以&b&正规计算机专业的教材,自始至终不会拿“如何使用某种GUI库”之类当重点讲,甚至可能压根就不讲&/b&。&/p&&p&因为被票友们视若珍宝的、关于如何写GUI程序之类玩意儿,实在太不值一提了,压根不值得在它上面耗费精力。&/p&&p&在下当年为公司考察选择各种图形库。其中GTK是从零开始学的,学了两天觉得差不多了打算练手,花两个小时弄了个“钻石迷城”游戏——有计分,无音乐。
后来把这个简单工程丢给一个打算学编程的哥们玩,结果这位玩了一个月的那个“钻石迷城”,愣是没看过我的实现代码……原因据说是看不懂,一行一行讲给他听都搞不懂。&/p&&p&至于如何实现一套好用的、可以和市面上已有产品竞争的GUI库……在你可以一头扎进命令行黑框框、轻易捣鼓出任何自己想要的东西之前,想都别想——更准确点说,恐怕是你到现在都想不通,为何实现一个GUI库,居然需要先钻进黑框框里面去……&/p&&br&&p&——没错,目标是这个的那些人,年复一年专心在黑框框里玩你们看起来low到爆简单到爆但凑到一块就没法看懂的一行行与或非顺序分枝循环……但你们都是他们的傻瓜用户。&/p&&p&甚至,他们哪怕稍微高看你们一点点、稍微多给你们一丁点做决定的自由,你们就充满恐惧的大叫“don't make me think!”&/p&&br&&p&你看,你要给这样两个人推荐同一条入门路线,乐子恐怕就太大了点吧。&/p&&br&&br&&p&知乎并非程序员社区,很多这方面话题的参与者仅仅是工作涉及编程,并没有多少是程序员。所以主流舆论对C充满了恐惧和……厌恶。对他们来说,C简直是必须立刻马上当即淘汰掉的、恐怖的老不死。以至于大言不惭的“C只能做底层”之类胡言乱语都出来了。&/p&&p&但是……这些才是程序员的地盘:&/p&&p&chinaunix首页,看看什么话题最吸引程序员:
&a href=&///?target=http%3A//www.chinaunix.net/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unix技术网 = 全球最大的Linux/Unix应用与开发者社区 = IT人的网上家园&i class=&icon-external&&&/i&&/a&&/p&&p&chinaunix论坛程序设计板块,看看哪个论坛帖子最多、最火爆:
&a href=&///?target=http%3A//bbs.chinaunix.net/forum.php%3Fgid%3D60& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&程序设计-ChinaUnix.net&i class=&icon-external&&&/i&&/a&&/p&&p&csdn论坛,点开左边的目录树,看看编程语言/框架都在讨论什么:
&a href=&///?target=http%3A//bbs.csdn.net/home%23& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CSDN论坛首页&i class=&icon-external&&&/i&&/a&&/p&&p&stackoverflow,哪些tags最常用到:
&a href=&///?target=https%3A///tags%3Ftab%3Dpopular& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Tags - Stack Overflow&i class=&icon-external&&&/i&&/a&&/p&&p&——————————————————————————————&/p&&p&对目标是第二条线的人来说,C的特点是:不作任何封装,把整个硬件、整个操作系统赤裸裸的摆在你的面前;同时它&b&又是一种高级语言&/b&,使得它的用户不必关注太多底层细节,于是在其上无论是讨论算法、还是谈论操作系统、网络协议栈、编译原理等等,都极为简单直观。&/p&&p&这些特点使得C极具生命力。甚至哪怕到了现在,C仍然是最为流行的编程语言(一直和java、c++联手垄断流行编程语言排行榜前三位——而且C经常在榜首;注意C和C++是分开统计的)。
&a href=&///?target=http%3A///articles/527159.htm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TIOBE 2016年8月编程语言排行榜:C语言排名创历史新低&i class=&icon-external&&&/i&&/a&&/p&&p&尤其是偏底层的系统级编程,更是C一家独大,除了C++别无对手。&/p&&p&别以为C只能做底层。真正复杂、高难度、对性能有苛刻要求的、支柱性的大项目,C仍然当仁不让、不可替代——我不知道那些说C不适合做项目的,究竟有没听说过linux,看过几个开源项目。&/p&&p&C只不过是太贵、所以不值得拿来做那些不值得花大精力深挖机器潜能、也不值得雇佣高级程序员精雕细刻的、堆积木性质的项目罢了——比如所谓的企业开发、比如开发部署一个网站……&/p&&p&不过,说到网站……或许你应该了解下apache/ngnix以及mysql等等都是什么写的 ^_^&/p&&p&没错。除了那些不上档次的、最为末端的企业及网站类应用外,其它任何领域,业界最好、最顶级的实现,大部分是C的。&/p&&br&&p&这就使得,无论你学什么,很容易就能拿到一大堆的C版本的开源例程;尤其是,若要学习真正能决定你将来能走多远的操作系统、数据库、编译器等基础原理方面的东西,更是几乎只有C一个选择。&/p&&p&不仅如此。C实现的任何东西,无论是操作系统还是编译器,全都会以赤裸裸的算法+数据结构的面目展示在你的面前。想知道什么,只要从一个API开始跟,很容易就能搞明白——跟一跟某个硬件相关API,甚至可以帮助你准确理解硬件。&/p&&p&彻底学通之后,任何技术、任何架构,都能一目了然。&/p&&br&&p&简洁直白、案例众多、学习资源丰富,这是C最为独特的优势。&/p&&p&所以,虽然想玩好指针之类危险特性并不算特别容易;但,&b&学基础算法本就不需要你玩这些危险特性&/b&;稍微学深一点,&b&和其他知识相比,指针又怎么都谈不到难上。&/b&反而是C一旦入了门,根本不假他求,很容易就能把整个计算机系统弄的通通透透——除了C,再没有第二种语言能有这么高的投入产出比。&/p&&blockquote&指针就是对内存最初步的掌控;连内存都玩不明白还奢谈什么“懂计算机”。
事实上,除了对面向对象的直接支持以及内置的内存回收机制等东西外,C并不比近年的各种高级语言少多少特性;而且,c写的unix的一切皆文件思想正是最为成功和最为著名的面向对象案例;需要关注其分配/回收的资源种类多如牛毛,并不仅仅内存一种,任何一种资源的泄露甚至只是不合理的占用都可能毁了一个项目:只靠一个内存自动回收哪救得了你。
所以,恰恰和外行想象的相反,真正庞大复杂的项目反而更需要天天和“资源管理”打交道的、有丰富开发经验的程序员(这正是c/c++程序员的强项:做不好资源管理的c/c++程序员还是早死早超生好了);那些温室里的、从未尝试过自己掌控资源生存周期的嫩苗绝干不了这事——&b&懒得管内存所以丢给垃圾回收、和不会管内存所以依赖垃圾回收,两者可绝不是一回事&/b&。
那些一说C就酸溜溜的扯汇编的,其实正暴露了他对计算原理的无知。&/blockquote&&br&&p&并不局限于资源的管理:专业的软件设计,学的是算法、是如何把一个极难的任务建模、分解、实现的学问:编译原理、操作系统等等,都不过是用于演示“如何庖丁解牛一个超级项目”的实例而已。&/p&&p&除了C之外,你到哪里找别的、有丰富的相关开源源码及其分析资料的语言?若学到这等程度了,连计算机原理都不会,还学个什么鬼?&/p&&br&&p&连个C指针都觉得难、然而却还挣扎着想入这个门的……简直不可想象。&/p&&p&可见,如果你的目标是专业的软件工程师,C就是最佳入门语言,没有之一。&/p&&br&&p&相比之下,同样的项目,其它语言因为封装的云山雾罩,哪怕是老鸟,想把人家的核心算法/架构从层峦叠嶂的各种委托、代理等等模式中剥离出来,都不是很容易的事,何况初学者。这反而不利于学习偏底层或者偏核心的知识——甚至很容易给初学者造成“不去看系统实现,因为不可能看懂”的“习得性无助”心理。&/p&&p&甚至,有调查显示,java程序员对自己每天都要打交道的JVM的理解,平均来说远不如C程序员——无论是入门级的知识点还是进阶知识点。&/p&&p&——————————————————————————————————————&/p&&p&但是,在知乎上,我也只会推荐python等脚本语言。&/p&&p&为什么?因为需求不同。&/p&&p&第一,&b&提问者本身就显示出某种急功近利、耐心缺乏的倾向。绝大多数还表现的特别明显&/b&。&/p&&p&比如说,极大一部分提问者是这样问的“想要转职/去xxIT企业,学XX可以吗/多长时间可满足要求”——&b&这压根就是玩票的票友嘛。&/b&你给票友推荐C?&/p&&p&显然,给他们推荐必须长时间学习深挖、必须有较为深厚的、各方面基础知识的C,不是装X就是找打。&/p&&br&&p&第二,知乎的提问者,大多不是初学者。他们是&b&未学者&/b&。
所谓初学者,显然应该是有一定的基础(起码得自己看过书、上机敲过例程吧)、但对计算机软硬件理解较浅、需要找一个突破口以学习提高的人。&/p&&p&对这类人,C显然是一把极佳的、便于开启操作系统和硬件大门的钥匙;对他们,不推荐C才有问题呢。&/p&&br&&p&但知乎的提问者,几乎无一例外,都是“若干种语言我选哪种学习”、“我想学编程我想将来写XXX学什么语言好”一类。&/p&&p&这种人压根连半步都没迈出去(因为随便他真把随便哪种最简单的语言学入门了、想要继续提高,都不会是这个问法),那么肯定得给他们推荐那些上手快、见效快的,不然这种磨磨唧唧的家伙恐怕连看完“序言”的耐心都不会有。&/p&&p&只有等他们上手之后,仍然有兴趣、有动力,自觉学有余力,这才能算初学者——到这时候,如果你打算深造,看会不会给你推荐C。&/p&&br&&p&第三,如前所述,知乎提问者,哪怕不急功近利,他们的&b&目标大多数时候也不是专业软件开发。&/b&&/p&&p&亦因此,你敢提C,他们就酸溜溜的对以汇编。&/p&&p&对他们来说,挖底层、挖算法,压根就不是目标;他们只关心怎么把自己的任务拼凑出来。&/p&&p&显然,只能给他们推荐那些简易、入门快、见效快、有大量辅助库可以马上拼凑出成品的语言——对这类人,你敢提指针,他们就止不住酸溜溜的心里难受。&/p&&br&&p&但,事实上,哪怕只是国内的chinaunix这样水平一般的程序员社区,指针相关的很多问题都没几个人乐意回答你:因为它太过浅显而且早就被那些初学的懒蛋们问成了“日经”,谁乐意日复一日的为他们浪费口舌。&/p&&br&&p&可见,对票友而言的入门,和对专业程序员而言的入门,压根就不是一回事。两者的差距,甚至可能和学开车和造汽车一样大——对后者来说,前者不过是一直拿积木拼来拼去罢了,什么时候入过门?&/p&
谁说C不适合入门?只不过你我对入门的定义未必相同。 想知道什么语言适合不适合“入门”,你起码得拿出地图看看人家所谓的“门”在哪里、并且有能力对比多条路线,这才有资格说哪条路线更好入门,对吧?比如说,如果两个人的目标分别是:
1、其实我什么都不…
楼上说了很多了,补充点具体的,以前 DOS下做游戏,操作系统除了磁盘和文件管理外基本不管事情,所有游戏都是直接操作显卡和声卡的,用不了什么驱动。&br&&br&虽然没有驱动,但是硬件标准还是放在那里,VGA, SVGA, VESA, VESA2.0 之类的硬件标准,最起码,你只做320x200x256c的游戏,或者 ModeX 下 320x240x256c 的游戏的话,需要用到VGA和部分 SVGA标准,而要做真彩高彩,更高分辨率的游戏的话,就必须掌握 VESA的各项规范了。&br&&br&翻几段以前写的代码演示下:&br&&br&&b&例子1: 初始化 VGA/VESA 显示模式&/b&&br&&br&基本是参考 VGA的编程手册来做:&br&&div class=&highlight&&&pre&&code class=&language-text&&INT 10,0 - Set Video Mode
40x25 B/W text (CGA,EGA,MCGA,VGA)
40x25 16 color text (CGA,EGA,MCGA,VGA)
80x25 16 shades of gray text (CGA,EGA,MCGA,VGA)
80x25 16 color text (CGA,EGA,MCGA,VGA)
320x200 4 color graphics (CGA,EGA,MCGA,VGA)
320x200 4 color graphics (CGA,EGA,MCGA,VGA)
640x200 B/W graphics (CGA,EGA,MCGA,VGA)
80x25 Monochrome text (MDA,HERC,EGA,VGA)
160x200 16 color graphics (PCjr)
320x200 16 color graphics (PCjr)
640x200 4 color graphics (PCjr)
Reserved (EGA BIOS function 11)
Reserved (EGA BIOS function 11)
320x200 16 color graphics (EGA,VGA)
640x200 16 color graphics (EGA,VGA)
640x350 Monochrome graphics (EGA,VGA)
640x350 16 color graphics (EGA or VGA with 128K)
640x350 4 color graphics (64K EGA)
640x480 B/W graphics (MCGA,VGA)
640x480 16 color graphics (VGA)
320x200 256 color graphics (MCGA,VGA)
EGA, MCGA or VGA ignore bit 7, see below
EGA, MCGA or VGA ignore bit 7, see below
- if AL bit 7=1, prevents EGA,MCGA & VGA from clearing display
- function updates byte at 40:49;
bit 7 of byte 40:87
(EGA/VGA Display Data Area) is set to the value of AL bit 7
&/code&&/pre&&/div&&br&转换成代码的话,类似这样:&br&&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&c1&&// enter standard graphic mode&/span&
&span class=&kt&&int&/span& &span class=&nf&&display_enter_graph&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&mode&/span&&span class=&p&&)&/span&
&span class=&p&&{&/span&
&span class=&kt&&short&/span& &span class=&n&&hr&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&k&&union&/span& &span class=&n&&REGS&/span& &span class=&n&&r&/span&&span class=&p&&;&/span&
&span class=&n&&memset&/span&&span class=&p&&(&/span&&span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&,&/span& &span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&k&&sizeof&/span&&span class=&p&&(&/span&&span class=&n&&r&/span&&span class=&p&&));&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&mode&/span& &span class=&o&&&&/span& &span class=&mh&&0x100&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&w&/span&&span class=&p&&.&/span&&span class=&n&&ax&/span& &span class=&o&&=&/span& &span class=&p&&(&/span&&span class=&kt&&short&/span&&span class=&p&&)&/span&&span class=&n&&mode&/span&&span class=&p&&;&/span&
&span class=&n&&int386&/span&&span class=&p&&(&/span&&span class=&mh&&0x10&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&);&/span&
&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&h&/span&&span class=&p&&.&/span&&span class=&n&&ah&/span& &span class=&o&&=&/span& &span class=&mh&&0xf&/span&&span class=&p&&;&/span&
&span class=&n&&int386&/span&&span class=&p&&(&/span&&span class=&mh&&0x10&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&);&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&h&/span&&span class=&p&&.&/span&&span class=&n&&al&/span& &span class=&o&&!=&/span& &span class=&n&&mode&/span&&span class=&p&&)&/span& &span class=&n&&hr&/span& &span class=&o&&=&/span& &span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&w&/span&&span class=&p&&.&/span&&span class=&n&&ax&/span& &span class=&o&&=&/span& &span class=&mh&&0x4f02&/span&&span class=&p&&;&/span&
&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&w&/span&&span class=&p&&.&/span&&span class=&n&&bx&/span& &span class=&o&&=&/span& &span class=&p&&(&/span&&span class=&kt&&short&/span&&span class=&p&&)&/span&&span class=&n&&mode&/span&&span class=&p&&;&/span&
&span class=&n&&int386&/span&&span class=&p&&(&/span&&span class=&mh&&0x10&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&,&/span& &span class=&o&&&&/span&&span class=&n&&r&/span&&span class=&p&&);&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&r&/span&&span class=&p&&.&/span&&span class=&n&&w&/span&&span class=&p&&.&/span&&span class=&n&&ax&/span& &span class=&o&&!=&/spa

我要回帖

更多关于 选股 知乎 的文章

 

随机推荐