1.背景知识之Linux背后的用用户人
2.每日一学:GitHub还是GitLab?谈谈两者的区别
3.有哪些值得推荐的C++书籍?
4.x,y 都是int, x++=y++ 为什么错?
5.å¦ä½ä½¿ç¨Oracleåå¨è¿ç¨çä¸ä¸ªç®åä¾å
6.码上去学:C++从入门到进阶的系列书籍推荐!
背景知识之Linux背后的户源人
. Linus和Bill 似乎在一夜之间,这个名字突然变得同象比尔。都包盖茨一样的括表耳熟能详。但是用用户比尔。盖茨,户源溯源码在哪里扫哪怕身价有数不清倍的都包百万美金,也永远不会变成Linux Torvalds。括表这位岁的用用户芬兰人,简单而强大的户源Linux操作系统的创造者,超越了盖茨的都包神话。也有传闻说盖茨是括表一个卓越的程序员,但Linus是用用户货真价实的高手。还在大学里时他就完成了一个货真价实的户源操作系统。年轻时的都包盖茨把拷贝他自己平庸的程序的程序员同行称为“贼”,而慷慨的Linus把他的杰作与全世界共享。哪个人,哪种运动会取胜,也许会决定技术发展的未来。 两年之前,如果有谁说技术巨人和微软的亲密合作伙伴HP,会忙着保证她生产的电脑顺利运行Linux,那会是天方夜谭。但Linus采取的开发模式,邀请全世界共享和改进他的个人原创,从而引发了一场革命。怀疑论者觉得微软面对美国司法部的起诉,把Linux标为值得重视的竞争对手,只是在制造假想敌,以洗脱垄断的罪名。但微软透露的真相也许比他们想象得多。去年岁末,一份称作“万圣节文档”的微软内部白皮书泄露到媒体,它的结论也许会让盖茨睡不安寝。 Linus被不少人认为是开放源码软件(open source software)的最佳代表人物,微软对付竞争对手的传统套路恐怕对他无可奈何。“Linux和其他开放源码软件,日渐可信地证实了OSS至少同商业软件同样强壮,如果没有超越后者的话。”微软工程师Vinod Valloppillil 的白皮书这样写道:“OSS聚积,发挥Internet上千百万人集体智能的能力令人惊异。” 但“万圣节文档”没有提到的是, Linus已经证明他是众多反盖茨人物中最高明,最强有力的一个。Oracle的CEO Larry Ellison的NC攻势只是过眼烟云,Sun的CEO Scott McNealy 尽管在JAVA上取得巨大的成功,但似乎已深陷在无条件反对盖茨的泥泞之中;相比之下,Linus 始终没有偏离自己的道路。尽管他自己绝不会承认,但你可以说他是一个圆滑老练的政治家。他避免了纯粹自由软件的支持者和以盈利为目的的厂商新人之间的对峙,将Linux搞得分崩离析。他欢迎所有能增强软件可靠性和可用性的商业Linux版本和商业Linux软件,也依然不遗余力地支持那些和他一起开创局面的自由软件激进派。 难以置信的是,在这个IPO和高科技亿万富翁层出不穷的时代,Linus并不显得急于将成功兑换成现钞。他仍然开着年初,离开芬兰开始在美国第一份工作(也是到目前为止唯一的工作--这是在硅谷)买的那一辆Pontiac Grand Am。一年之前,当Santa Clara 的那间小公寓再也住不下Linus,他的幼儿园教师妻子和他们的两个女儿时,他们租了所看的第一间房子--就在马路对面。关于他的雇主,高度保密的 Transmeta公司的各种谣言,在硅谷甚嚣尘上,但到目前为止,Linus似乎没有什么大发一笔横财的迹象。 面对面聊天时,这位被大多数人只以名字Linus相称的人,戴着眼镜,语音轻柔,容易接近,对自己的才能和成就充满自豪,而且十分幽默。他从前是出名地逮什么吃什么,现在则对寿司情有独钟。由于编程太多,他的肚子已经有点儿凸,不过他的声音和他顽童般的笑容里远没有失去芬兰特色的那种轻快。 Linus看来是一个平民主义者,他希望打破垄断性软件定价的思想方式,也反映在他的其他口味上。比如,他不买精装书,因为他相信精装书卖不太好,所以定价一定偏贵。同样,他更喜欢好莱坞的娱乐片,而不是欧洲的高品位艺术**。他的父亲在电台工作,他的母亲翻译报纸新闻,叔叔为芬兰电视台工作,祖父是报纸记者,所以他理解新闻媒体,而且似乎也对于自己越来越出名自得其乐。2. 叛逆,叛逆 问:你是否认为自己是传统的,正面意义上的黑客,一个叛逆者?我觉得仅称你为”一心编程的程序员“是不够的。 答:我一般试图避免用黑客这个词。水下火箭指标源码在和其他搞技术的人私下交谈时,我会称自己黑客。但同媒体接触时我只说“程序员”什么的,因为现在黑客往往是另外一个意思。 问:那么“叛逆者”这个标签如何? 答: “叛逆者”意味着你为某种事业而战,而且是在反对另一些东西。我不说自己叛逆,我说自己是有准则的。(ethical instead of rebel)叛逆的根本意义在于反对,而我觉得有自己的目的,两者的区别就是这样。我有自己的准则,我不关心别人是否也相信这些准则,我觉得这完全是个人的选择。 问:那么你如何描述你的准则和目标呢? 答:我的基本生活准则是:“己所不欲,勿施于人”,这不是仅限于基督教的思想,这是世界性的。这条准则很简单,而且在绝大多数情况下它可以告诉你该做什么。如果你举棋不定“我该干什么”,你可以自问“我会希望他(她)干什么?”马上你就知道答案了。 问:你是否相信你的工作或者你的技术中,有一定社会或政治的因素? 答:从开始就不是这样。一开始和社会完全无关,最初的动力是技术和我的个人兴趣。没有政治性是因为:政治在本质上就是要改变人的想法,我一直不希望这种事发生在我头上。 但许多其他的“开放源码”人士未必和我一个想法。其中许多是政治性的:一些人试图让另一些人接受自己的观点,我不希望自己那样做。我也会谈自己的看法,但只是在别人问我之后。 问:有许多机会你可以下海,或者决定Linux操作系统应该商业化,但你显然没有这样做,这让我很奇怪。为什么? 答:这是我个人的兴趣问题。吸引我搞Linux的一直是技术。它一开始就不是为了赚钱,即使到了可以赚钱的时候,那也不是我的本意。商业化会改变我的动机。 我很高兴有人在Linux上赚钱,那样增加了Linux的深度,也引入了新的动机和新的因素,如果不是因为商业目的那是不可能的。但我开始Linux的时候,商业化并不是我的选择。 问:许多人会认为那是一个困难的抉择。但你却处之泰然,你觉得是为什么呢? 答:也许在美国这是一个困难的抉择,但在世界的其他许多地方就未必了。美国是以金钱为中心的,每个人都重视钱,这当然也有好处。 但在芬兰就不一样了。那里的文化背景下,成功是值得赞赏的,但你也欣赏别的东西,也许更多一些。比如说我的家族就很重视学位。他们认为学习是重要的,他们并不太在乎钱。3. Linus 2.0 问:围绕着你在Transmeta的工作有着重重的谜团,能给我点提示什么时候可以真相大白吗? 答:不行。也许明天就可以,也许得等年。 问:是Transmeta找你还是你找Transmeta? 答:双向选择吧。我认识一个瑞典人,他在Transmeta工作。他到了赫尔辛基呆了一天和我见面,那时我说:“总算可以毕业了。”,因为那时我已经几年没有好好放松了。然后他就问我是否愿意去 Transmeta,然后我和他的老板谈。一周之后,年的秋天,我就坐飞机到加州来看。 问:我理解你不能透露和工作有关的事情,但是可以告诉我这份工作哪一点让你兴奋吗? 答:部分原因是那时我已经在Linux上干了6年,也希望有一些别的东西。我可不想在一根绳上吊死。我不希望Linux是我生活的全部,我希望能够找到一些本身就能激励人的东西。而且,小公司人情味比较足。还有,涉足一些世界上没有其他人涉足的领域也让人兴奋。 问:那些东西和Linux无关吧? 答:他们在内部就用Linux。我每天都用。他们也欢迎我在Linux上面的工作。一方面是因为公关效应,另一方面是因为内部也用得上。 问:但你在Linux上的工作是没有报酬的。许多人奇怪你怎么会花这么多时间在没有钱的... 答:即使是那些无法想象世界上有人做事会出于兴趣的人--那种人是挺可悲的,但也是有这样的人,我也可以向他们解释:年之后Linux要是真的一帆风顺,我就要风得风,亲测源码分享要雨得雨了,就象在银行存钱一样。这不是我的目的,但可以这样告诉那些除此之外就无法理解的人。 我认为自己是一个艺术家,在做自己乐意做的事情。而且我也不用活得特别惨,因为程序员的待遇并不差。4. 时间就是一切 问:你对资本主义的看法很有趣。看来你也相信自由软件的一些观点,但也不反对为软件和服务收费。什么情况下收费更合理,什么情况下免费更合理呢? 答:收费总是合理的。但当我开始时,我无法使用商业软件,因为它们太贵了。Linux存在的部分原因就是,我不希望任何人再陷入那种境地--这就是“己所不欲,勿施于人”。但同时我也不认为收钱就有错。 我并不反对钱。钱是个有趣的概念,但你必须选择最重要的东西?Linux好就好在,如果你是一家公司而且愿意付钱买一年天,一天小时的服务,你也得付一大笔钱--即使在Linux上那也是昂贵的,但如果你是一个穷学生,或者在第三世界国家,也许Linux会带给你接触一些新鲜事物的机会。 问:Linux发展的速度或者Linux发展的方向曾让你始料不及吗? 答:去年的事情也是经过一定酝酿过程的。在某种程度上,当一个公司决定支持Linux后,其他这么多公司会纷纷响应,这是让人吃惊的。不过,我从来没有在家里看得合不拢嘴,除了“哇”以外就说不了别的,我的反应更象是“嗯,够酷的,真的发生了。” 问:是不是可以说Linux很好地把握了时机? 答: Linux的成功是时机、需求和市场机会的组合。比如,Linux刚刚开发时,人们没有CDROM。Linux 面世后一年,CDROM就随处可见,于是突然就有了一种高性能价格比的商业化发行Linux的可能。所以,时机确实很好。Internet也是一个大好机会。Internet流行起来之前就已经有Linux了,但网络的基础架构一旦建立,Linux确实也或多或少地从中得益。 问:我还觉得从微软那方面的事情发展来看,Linux的出现也是恰逢其时? 答:出于公关的原因,司法部的起诉变成了一个对付微软的大聚会。两年以前,没有人质疑过微软,大家认为微软做的事情是理所当然的。人们崇拜微软:大公司,成功,大把赚钱,人们觉得那就是美国梦。司法部的起诉的一个结果是,一些原先喜欢微软的人现在改主意了。5.开发源码是民主 问:而且他们现在也知道除了微软以外还有别的选择? 答:你提到的这个事实意味着,突然之间你开始注意到有别的选择。以前人们并不寻找其他选择。现在,即使你不从Windows转到Linux,或者作其他的大改变,你还是会说:“看来微软说的东西还得想一想” 我认为这很重要。6.开放 vs. 封闭 问:你如何对比你开发Linux的开放源码模式和微软开发Windows和Windows NT的封闭模式? 答:在Linux上,系统的使用者可以影响开发的方向。从用户无须放弃控制这个角度说,这就是民主。每个人都可以做任何的事情。当然,基本前提是你必须有足够的能力,不过那也不失为区分干活的人和不干活的人的一种好办法。而且,即使是不修改软件的人也可以提建议,作测试,等等。 我想,作为一种开发模式,开发源码是相当优越的--尤其是与传统的商业化封闭开发环境相比。问题的本质是如何激励人去创造。 但确实有许多工作怎么样也算不上有趣,一项工作如果没有趣的话,必须靠其他的激励手段。最明显的就是通过钱。从某种程度上说,在封闭的环境下更容易挣钱。封闭模式依靠的是不给其他人提供完整的信息,从而限制竞争。限制竞争对于公司是有利的。 问:你有什么比喻可以描述这两种模式的差别吗? 答:我会这样说:封闭模式是一家出版社,它掌握的jdbc源码解析infoq是铅字而不是语言。用户有读的自由,写的自由,但出版社决定什么样的东西可以出版发行,流传于世。你可以读,也可以用手写,但如果想要对书做什么改进的话,就得自己从头开始,或者求出版社。 问:那么,开放源码模式的比喻就应该是一台打印机喽,打印机什么都不限制。 答:对,你可以有任意多台的打印机,而且打印机之间可以共享字体。 问:这是一个有趣的比喻。为什么Linux和开放源码模式如此成功,能告诉我你的看法吗? 答:Linux能走到今天这一步,其中一个原因就是,它是弱者。在某种程度上,市场的力量对Linux的开发者没有太大的意义。人们开发Linux,是因为他们感兴趣的东西得不到足够的市场份额,而且他们也没有什么董事会跟在后面,必须每个季度解释财务状况。 你改变了游戏规则,从而也改变了市场。(You also change the market by changing the rules in ways that Microsoft isn't willing to fail on)源代码公开变成了一个卖点。突然之间有了一条新的游戏规则,并非所有的人都在乎这条规则,但只要有人在乎,他会不假思索地拒绝微软。这就象两军对阵一样:你不能让敌军挑选战场,你必须掌握主动。 问:你认为Linux有可能使微软或者其他的主流厂商改变他们的战略或者战场吗? 答:某种程度上我希望会是这样。用一个我自认为贴切的比喻来解释:让我们看当前美国最大的 5家软件公司,把他们和年代美国最大的5家汽车制造商作个比较。当时所有的汽车公司都在新功能,新附件上竞争,每年都会推出新车型。 听起来是不是很耳熟?现在每年都会有个新版本的Windows。当时汽车公司的工作是让人们注意每年的车型翻新。所以年的凯迪拉克和年的凯迪拉克差别很大。人们当然就会注意车型。为什么?公司就是希望人们在乎自己开的是什么车型,几几年的车型--新年的新车型会给公司赚取大量的利润。尽管前一年的车型照样工作得很好,公司还是希望卖新车型。 我和Linux就象当年的日本汽车制造业。确实,历史上有年代石油危机,还有其他的因素。但问题的本质是美国的汽车业并不关心质量,而是关心新的功能,还有每年的新车型。然后,日本汽车出现了,一开始他们质量虽好,名声也不见得那么大,但是渐渐地用户们明白了:“嘿,日本汽车造得就是好。它们是没有流线型尾翼(fin),但是话讲到底,我每年换车干什么?” 我相信这是一个准确的比喻。如果微软能象美国汽车工业那样,改变它的做法,我会很高兴。如果微软真能改而在质量上和Linux竞争,那就是我的胜利。 问:微软的Steve Ballmer (第二号人物)最近提到开发Windows的源代码,你对此有何看法? 答:我所有的开发工作都是在Internet上完成的,你在Internet上学会的头一件事就是光说不练靠不住。 (and the first thing you learn on the Internet is that talk is cheap.) 除非看到了结果,否则我不相信任何言辞,这对所有的东西都是一样的,包括Ballmer的说法。眼见为实嘛。 (Show me the money! )7. Linux vs. NT 问:谈到Ballmer和他的真正用意,你觉得微软是确实害怕Linux呢,还是它只不过利用媒体炒做对付司法部的起诉? 答:我相信一开始这是微软的有意操作,特别是去年秋天Linux刚开始引起注意的时候。微软内部没有人会这样认真地看待Linux,但他们看到它可以利用,作为法庭辩护的一个依据。但他们失算了,事情的结果是引起了许多舆论界人士的兴趣:“这个Linux到底是什么东西?” 问:你认为Linux有可能比NT使用更广泛吗? 答:如果只是比较Linux和NT,我的回答是肯定的。Windows NT和Linux占有差不多的市场份额。〖编者按:根据IDG的报告,年底,NT的服务器市场占有率为%,Linux %,其他UNIX %,NETWARE %。将来Linux会超过NT。那一天到的时候我不会太奇怪的。真正的目标是桌面系统。这不可能在一年、两年中发生,重庆源码时代java但也许会在3年,4年,5年间实现。 问:你认为两到三年内Linux会挑战微软在桌面市场的地位? 答:是三到四年。我希望那时Linux会成为非技术的电脑用户的选择之一。 问:那会对电脑工业和微软产生什么影响呢? 答:未必会到那样的地步。我只是认为,用户没有选择的市场是病态的。 问:你用病态这个词? 答:是的,是病态。你有一个非常广阔、复杂的市场,但有一家公司控制着这市场的绝大部分。不过最终垄断是维持不下去的。 在新兴的市场中,往往一个公司掌握着巨大的实力。当年的石油大王如此,当年的汽车工业如此,当年的电脑业也是如此,那时人们认为IBM是不可战胜的。 最后总会演变成五六家大公司并立的局面,那样才会稳定。所以我认为当前的市场是病态的。8.今后5年的道路 问:你对自由软件和商业力量之间的对立有何看法?有些纯粹主义者不喜欢Redhat或者任何其他发售Linux 商业版的公司,他们认为Linux应该保持永远免费。 答:我试图避免看事情只分黑和白。我的观点是:有了Linux,你确实可以避免商业化。可以从网上下载你需要的一切,一分钱都不用付。但坦白的说,我不希望再下载所有的东西了。现在,如果有了一台新机器,我会插进一张Redhat或者Suse的光盘,然后安装,然后再加上我自己需要的其他东西。我不需要为光盘付钱,但如果有必要的话,我是乐意掏钱的。它们确实是提供了真正的服务。这就是选择。如果你看事情一定要分黑白,认为Linux就该彻底免费,那么你也是作出了自己的选择,但我觉得那样做是局限自己。 问:看来你并不担心Redhat和诸如此类的公司会操纵Linux? 答:那是因为Redhat这样的公司不会希望接管内核的开发--这个代价他们是明白的。他们会希望员工中有许多内核开发者,一旦发生问题,可以靠自己人解决。 但他们本身并不想涉足内核开发。一个象样的商业公司,总会花时间做市场调研,搞清楚客户在做些什么,可以带给用户怎样的额外功能或价值,保证产品容易安装,解决重要的细节漏洞。关键是成品--完成一个产品,还有市场运作和组织运营。(It's about finishing touches, and it's marketing and logistics. ) 问:你认为5年之后,Linux会发展成什么样? 答:对我来说,最有趣的一点始终是它各种各样的用途。我对嵌入市场感兴趣,因为那里会有些别处找不到的特殊用途。从技术的角度,超级计算机总是很性感的,但是从另一方面说,它们有趣也是因为有别处没有的特殊需求。 我觉得最有趣的市场是桌面市场,因为桌面没有任何特殊化。而反过来讲,这意味着永远不会有一个十全十美的解决方案--人们要用的东西太多了。技术上,这是一个极其困难的问题,这也就是为什么我特别关注桌面。我希望在5年之内,你可以看到Linux成为桌面系统的一个选择。也许不会替代微软,但至少会成为一个真正的选择。当年有人去电脑商店买他的第一台电脑时,他们会停下来考虑一下,到底是要Linux,Windows还是MacOS。 问:Linux和开放源码模式看来工作得很好,是否有其他新的商业模式引起你的兴趣呢? 答:有一种让我很感兴趣,但无法让我相信,那是“Internet语言化” (internet phrasing)的商业模式,内容包括把E-加在公司的名字前头,然后把股票的市值炒上一个数量级。我觉得这很有趣,但长远来看不会成功。 问:那你认为会发生什么呢? 答:我认为传统工业会非常重视Internet。一小部分走在前列的公司会一战成名,然后发展不错;剩下的成功机会十成中可能超不过一成。也许Yahoo会生存下来--它的名声太显赫了,单凭这名声就可以赚钱--品牌认同还是很重要的。但通过现在的商业模式他们不会赚钱,也许他们自己已经明白了。 问:最后的问题,你认为软件产品的价格走向会怎样? 答:当年PC公司和微软是通过制作廉价的软件进入软件普遍昂贵的市场的。你看这些规模小,但是富于进取心的公司--例如Borland,现在叫 Inprise,靠做编译器成名,或者微软,靠的是BASIC,他们就是这样进入市场的。令人沮丧的是,现在微软掌握掌握市场如此牢固,新一轮的涨价又开始了。Inprise当年率先推出价格低于美金的编译器,引起了轰动,但当时的轰动已被淡忘了。我们又回到了软件价格居高不下的时候,因为又有大公司可以说:“你就该付这么多。” 我希望我们会再有一次那样的轰动。现在的经济模式允许以高价销售软件,但我相信那不会持久。这使有些人认为我是共产主义者,但我不是--我绝对相信竞争。我只是相信竞争会获胜,价格会再一次下跌。
每日一学:GitHub还是GitLab?谈谈两者的区别
VCS又名源代码管理(SCM)系统,旨在让开发人员、设计人员同时开发一个项目。它能够确保每个人都可以访问最新代码,并同步自己的修改。
然而,这说起来容易做起来难。
为了实现这一点,Linux之父Linus Torvalds发明了免费的开源分布式版本控制系统Git。Git的表现要比Apache Subversion、并发版本系统(CVS)、Perforce和Rational ClearCase要出色的多,因此之后大多数VCS服务的名称中都包含了“Git”。
如果开发人员在内部构建程序,那么只需用到本地Git。Git甚至还可以个人服务器或云上的集中式VCS,开发人员可以与世界各地的伙伴一起开发项目。
但是,如果开发人员的需求增加,那么使用GitHub或是GitLab也是不错的选择。
GitHub是基于Git的在线代码仓库,也是全球最大的代码托管平台,开发人员可以在GitHhub上进行交流和学习。年2月,Chris Wanstrath、PJ Hyett、Tom Preston-Werner和Scott Chacon使用Ruby on Rails开发GitHub。由于它是最早的分布式版本控制系统,GitHub之后发展成为大多数开源代码的存储库。截至年月,GitHub拥有超过万开发人员以及超过2亿个存储库,其中至少有万个公共存储库。
年乌克兰开发人Dmitriy Zaporozhets和荷兰开发人员Sytse Sijbrandij开发了GitLab,它拥有在单个应用程序中开发、保护和操作软件的能力。GitLab约有万用户,其中有万活跃用户。
GitLab最初用Ruby编写,之后又用Go重写了部分内容。最初,它作为源代码管理平台,用于在软件开发团队内进行协作,后来发展为涉及软件开发生命周期甚至是整个DevOps生命周期的平台。现阶段GitLab使用的软件技术包括Go、Ruby on Rails以及Vue.js。
在某种程度上,GitHub和GitLab非常相似。两者都在Linux上运行,并且都带有问题跟踪器,提供大量第三方集成和导入工具。
它们还为提供了命令行界面(CLI)以及基于Web的界面。在GitLab中,用户界面采用Vue.js编写,用的是自己的设计系统。而GitHub的用户界面Desktop可作为Windows或macOS程序使用。同时开发人员还可以将Visual Studio与GitHub一起使用。
虽然两者都支持开源,但存储库使用的是不同的编程模型。GitLab使用的是开放核心业务方法,社区版保持免费和开源,而企业版有更多的功能。而对于GitHub来说,尽管它的代码涉及许多开源代码,但它不是开源项目。
不过两者都提供基于Web的存储库,可以进行开源且基于Git的代码管理,并支持远程存储库的本地文件更改。不管是只需要Git的基础功能,还是需要开放所有功能,GitHub和GitLab都是可以更改的。
除此之外,由于年月日GitHub被微软以亿美元收购,许多人选择放弃GitHub。对于一部分人来说,就算微软支持开发开源软件,微软也永远是个“反派”。但现实就是放弃GitHub并选择GitLab的人并不多。
GitHub如今成为VCS领域中的巨头。根据编程工具公司JetBrains的数据,有%的开发人员使用GitHub,而使用GitLab的为%,使用BitBucket的为%。
造成这一局面的主要原因在GitLab内置了持续集成/持续交付(CI/CD)以及DevOps流程。而GitHub则是由开发人员选择CI/CD工具并进行集成。一般来说,GitHub用户会选择第三方CI程序,例如Jenkins、CircleCI或TravisCI。
另一个区别在于GitHub看重速度,而GitLab看重安全性。
GitHub还支持将新分支与主分支合并。这样,用户就可以进行快速部署,出现问题还可以恢复到上一个版本。
在GitLab中,用户可以在master分支外创建多个稳定的分支,但这意味着用户需要进行多次的测试,合并时需要进行多次代码审查。
但是GitLab提供了完整的软件开发解决方案,这是一个完整的DevOps平台。GitLab可以与许多第三方程序和平台集成,其中包括Jira、Microsoft Teams、Slack、Gmail等等。
另一方面,GitHub提供的服务较少,但有许多与外部程序和服务集成的方法,开发人员可以通过GitHub Marketplace集成数百个其他程序。
对于个人或是小型团队而言,GitHub和GitLab都提供免费版本,其中含有无限的公共库和私人库。但是如果是大型互联网公司的话,免费版本的功能显然是不够的,公司可以针对不同的需求而进行选择。两者均为基于Web的Git仓库,可以允许开发人员进行储存、分享、发布和合作开发项目。
若是更看重代码的安全性,GitLab无疑是更好的选择;但是若是开源项目,GitHub仍然是首选。
有哪些值得推荐的C++书籍?
C++是一种广泛使用的编程语言,有许多优秀的书籍可以帮助你深入学习和理解它。以下是一些值得推荐的C++书籍: 1.《C++Primer》:这是一本非常经典的C++入门书籍,适合初学者。它详细介绍了C++的基本概念和语法,并提供了大量的示例代码和练习题。 2.《EffectiveC++》:这本书由ScottMeyers撰写,是一本关于C++最佳实践的指南。它涵盖了许多重要的主题,如内存管理、异常处理和泛型编程等,对于提高C++编程技巧非常有帮助。 3.《深入理解计算机系统》:这本书虽然不是专门讲解C++的,但它对计算机系统的底层原理进行了深入的探讨,包括处理器、内存和操作系统等方面。这对于理解C++的运行机制和优化代码非常有帮助。 4.《STL源码剖析》:这本书由NicolaiM.Nestorov撰写,深入剖析了C++标准模板库(STL)的实现原理。通过阅读这本书,你可以更好地理解STL的工作原理,并学会如何高效地使用STL。 5.《设计模式:可复用面向对象软件的基础》:这本书介绍了常见的设计模式,如单例模式、工厂模式和观察者模式等。虽然它是以Java为例进行讲解的,但其中的思想和原则同样适用于C++编程。 6.《算法导论》:这本书是计算机科学领域的经典教材,介绍了各种常见的算法和数据结构。虽然它不是专门讲解C++的,但对于提高算法设计和分析能力非常有帮助。x,y 都是int, x++=y++ 为什么错?
赋值运算需要左值,而x++不是左值。x++的本意是使用x的值,在使用后将x自加1,那么如果把x++用在赋值运算的左边的话,赋值时是赋给原先的x还是自加后的x呢?显然是未定义的,所以这种操作是错误的。
下面转一篇关于左值和右值的文章,相信会对你帮助很大的。
左值(lvalue)和右值(rvalue)是编程中两个非常基本的概念,但是也非常容易让人误解,看了很多文章,自我感觉真正将这个问题讲的很透彻的文章还没有看见,所以自告奋勇来尝试一下。如果左值右值的概念不是非常清楚的话,它们迟早会像拦路虎一样跳出来,让你烦心不已,就像玩电脑游戏的时候每隔一段时间总有那么几个地雷考验你的耐性,如果一次把所有地雷扫尽就好了。:)
左值(lvalue)和右值(rvalue)最先来源于编译理论(感谢南大小百合的programs)。在C语言中表示位于赋值运算符两侧的两个值,左边的就叫左值,右边的就叫右值。比如:
int ii = 5;//ii是左值,5是右值
int jj = ii;//jj是左值,ii是右值
上面表明,左值肯定可以作为右值使用,但反之则不然。左值和右值的最早区别就在于能否改变。左值是可以变的,右值不能变。注1
注1:这一点在C++中已经猪羊变色,不再成立。拱猪游戏还是挺好玩的,我还真抓过好几次全红心,不过真的好险。:)
在很多文章中提到,在C++中,左值更多的指的是可以定位,即有地址的值,而右值没有地址。注2
注2:这一点仍然不准确,我在程序中生成一个临时右值std::vector(),你能够说它没有地址吗?难道它是没有肉体的鬼魂或幽灵?它是有地址的,而且它也是绝对的右值。
在现代C++中,现在左值和右值基本上已经失去它们原本所具有的意义,对于左值表达式,通过具体名字和引用(pointer or reference)来指定一个对象。非左值就是右值。我来下一个定义:
左值表示程序中必须有一个特定的名字引用到这个值。
右值表示程序中没有一个特定的名字引用到这个值。
跟它们是否可以改变,是否在栈或堆(stack or heap)中有地址毫无关系。
1.左值
在下面的代码中:
int ii = 5;
int const jj = ii;
int a[5];
a[0] = ;
*(a+3) = ;
int const& max( int const& a, int const& b ) //call by reference
{
return a > b ? a : b;
}
int& fun(int& a) //call by reference
{
a += 5;
return a;
}
ii,jj,a[0],*(a+3),还有函数max的返回值比如max(ii, jj),注3函数fun的返回值fun(ii)都是左值。,它们都是有特定的引用名字的值。ii,jj,a[0],*(a+3),max(ii, jj),fun(ii)分别就是它们的名字。
注3:在这里有一个不太容易分清楚的盲点。那就是有人会问max(8, 9)到达是左值还是右值,C++标准规定常量引用(reference to const)可以引用到右值,所以max(8, 9)似乎应该是右值,不过不管它是左值,还是右值,我们都不能试图去改变它。为了与前面的概念一致,我认为它是左值,不可改变的常量左值。
左值有不能改变的,即被const所修饰的左值,比如上面的jj,max(ii, jj)都是被常量(const)魔咒所困住的左值。
没有被const困住的左值当然是可以改变的,比如下面的代码都是成立的:
ii = ;
a[0] = ;
fun(ii) = ; //OK!
我们的眼睛没有问题,fun(ii) = ;完全正确,因为它是可以改变的左值。所以我们看STL的源码,就会理解std::vector中的重载operator[]运算符的返回值为什么要写成引用,因为operator[]必须返回左值。
2.右值
没有特定名字的值是右值。先看下面的代码:
std::list();
std::string(“It is a rvalue!”);
int fun1() //call by value
{
…
}
int* fun2() //call by reference
{
…
}
其中std::list(),std::string(“It is a rvalue!”),函数fun1的返回值fun1(),函数fun2的返回值fun2()都是右值,它们的值都没有特定的名字去引用。也许有人会奇怪,fun2()也是右值?最前面的max(a,b)不是左值吗?
请看清楚,函数fun2的返回值是pointer,pointer也是call by value,而函数max的返回值是reference,reference是call by reference。所以说C++中引入reference不仅仅是为了方便,它也是一种必须。注4
注4:Scott Meyer写的《More Effective C++》的条款1专门讲了pointer和reference的区别,写的很好,辨别的非常清楚。
fun2()是右值,但 *fun2()却是左值,就跟经常看到的*p一样,所以看C++库代码的时候,会发现重载operator*的函数返回值是reference。
当然我还遗漏了一种右值,那就是字面上的(literal)值,比如5,8.,’a’等等理所当然的都是右值。
右值最初出现的时候,一个最大的特征就是不可改变。但就跟我们的道德标准一样,时代不同了,标准也变化了,以前的三纲五常早已经被扔到历史的垃圾堆里面了。
C++中有可以改变的右值,而且这个特性还非常有用。那就是用户自定义的类(class)的构造函数生成的临时对象。比如:
std::vector(9),std::deque(),……都是可以改变的右值。在Herb Sutter的《More Exceptional C++》中的条款7的page页有这样几行代码:
// Example 7-2(b): The right way to shrink-to-fit a vector.
vector<Customer> c( );
// ...now c.capacity() >= ...
// erase all but the first elements
c.erase( c.begin()+, c.end() );
// the following line does shrink c's
// internal buffer to fit (or close)
vector<Customer>( c ).swap( c );
// ...now c.capacity() == c.size(), or
// perhaps a little more than c.size()
认真看几遍,你会发现但vector的大小增大到一定程度,你又用不着这么多空间的时候,你会想办法把它收缩到最合适的大小,但利用别的办法比如调用成员函数reserve()都无法办到,这个时候就必须利用右值可以改变这个性质了。
vector<Customer>( c ).swap( c );这行代码就是点睛之处。
首先使用复制构造函数生成临时右值vector<Customer>( c ),这个右值正好是合适大小,然后和c交换注5,c就变成合适大小了,最后在整个表达式结束的时候,这个临时右值析构归还内存空间。真是绅士一般的优雅!
注5:这个时候这个临时右值就发生了改变。
如果还不理解,可以看看书,或者直接看库的源代码。
至于为什么会这样?我思考了一下,我想是这样的,我们看类(class)的数据布置结构,会发现它的每一个数据成员都是有名字的,我想编译器在编译的过程中,都会生成一个外部不所知的对这个临时对象右值的名字引用,但需要改变这个临时对象的时候,这个名字就用上了。比如:
class Point
{
public: //纯粹为了方便,我把数据成员公开,现实中尽量不要这样用
int x, y ,z;
……//其他各种成员函数
};
我们现在就可以改变右值,用到了匿名的引用名字。
Point().x = 6;//改变了右值
Point().y = 6;//同意改变了右值,不过注意,这个右值跟上面的不是同一个。
总结
左值和右值的真正区别我想就是这些了,左值表示有特定的名字引用,而右值没有特定的名字引用。当然我仍然会有疏忽,希望大家能够提醒我,指正我的不足。
前两天看Herb Sutter从邮件中寄来的新文章(我订阅他的新文章邮件通知),一篇是讲Tuple数据结构的,没有什么新意,以前好像看过,还有一篇名字是:(Mostly)Private,地址为/documents/s=/cujcexpsutter/ 内容本身并不深,但看完文章,发现随处可见C++的波诡云谲,又会对什么叫袖里乾坤,滴水藏海多一份感性认识。
在下一篇文章我想从不同于一般的角度,从自己的经历谈谈在校毕业生在IT行业怎样找工作,我想会让所有读者都有一些思考,不仅仅是求职者。题目我已经想好了,就叫《扮虎吃猪》,不过现在我有一些别的事情要忙,所以可能会让大家等几天。
转载请注明来源,谢谢!
å¦ä½ä½¿ç¨Oracleåå¨è¿ç¨çä¸ä¸ªç®åä¾å
楼主æ¨å¥½
---å建表
create table TESTTABLE
(
id1 VARCHAR2(),
name VARCHAR2()
)
select t.id1,t.name from TESTTABLE t
insert into TESTTABLE (ID1, NAME)
values ('1', 'zhangsan');
insert into TESTTABLE (ID1, NAME)
values ('2', 'lisi');
insert into TESTTABLE (ID1, NAME)
values ('3', 'wangwu');
insert into TESTTABLE (ID1, NAME)
values ('4', 'xiaoliu');
insert into TESTTABLE (ID1, NAME)
values ('5', 'laowu');
---å建åå¨è¿ç¨
create or replace procedure test_count
as
v_total number(1);
begin
select count(*) into v_total from TESTTABLE;
DBMS_OUTPUT.put_line('æ»äººæ°ï¼'||v_total);
end;
--åå¤
--线对scott解éï¼alter user scott account unlock;
--åºä¸ºåå¨è¿ç¨æ¯å¨scottç¨æ·ä¸ãè¿è¦ç»scottèµäºå¯ç
---alter user scott identified by tiger;
---å»å½ä»¤ä¸æ§è¡
EXECUTE test_count;
----å¨ql/splä¸çsqlä¸æ§è¡
begin
-- Call the procedure
test_count;
end;
create or replace procedure TEST_LIST
AS
---æ¯ç¨æ¸¸æ
CURSOR test_cursor IS select t.id1,t.name from TESTTABLE t;
begin
for Test_record IN test_cursor loop---éå游æ ï¼å¨æå°åºæ¥
DBMS_OUTPUT.put_line(Test_record.id1||Test_record.name);
END LOOP;
test_count;--åæ¶æ§è¡å¦å¤ä¸ä¸ªåå¨è¿ç¨ï¼TEST_LISTä¸å å«åå¨è¿ç¨test_countï¼
end;
-----æ§è¡åå¨è¿ç¨TEST_LIST
begin
TEST_LIST;
END;
---åå¨è¿ç¨çåæ°
---IN å®ä¹ä¸ä¸ªè¾å ¥åæ°åéï¼ç¨äºä¼ éåæ°ç»åå¨è¿ç¨
--OUT å®ä¹ä¸ä¸ªè¾åºåæ°åéï¼ç¨äºä»åå¨è¿ç¨è·åæ°æ®
---IN OUT å®ä¹ä¸ä¸ªè¾å ¥ãè¾åºåæ°åéï¼å ¼æ以ä¸ä¸¤è çåè½
--è¿ä¸ç§åæ°åªè½è¯´æç±»åï¼ä¸éè¦è¯´æå ·ä½é¿åº¦ æ¯å¦ varchar2()ï¼defaul å¯ä»¥ä¸åï¼ä½æ¯ä½ä¸ºä¸ä¸ªç¨åºåæ好è¿æ¯åä¸ã
---å建æåæ°çåå¨è¿ç¨
create or replace procedure test_param(p_id1 in VARCHAR2 default '0')
as v_name varchar2();
begin
select t.name into v_name from TESTTABLE t where t.id1=p_id1;
DBMS_OUTPUT.put_line('nameï¼'||v_name);
end;
----æ§è¡åå¨è¿ç¨
begin
test_param('1');
end;
default '0'
---å建æåæ°çåå¨è¿ç¨
create or replace procedure test_paramout(v_name OUT VARCHAR2 )
as
begin
select name into v_name from TESTTABLE where id1='1';
DBMS_OUTPUT.put_line('nameï¼'||v_name);
end;
----æ§è¡åå¨è¿ç¨
DECLARE
v_name VARCHAR2();
BEGIN
test_paramout(v_name);
DBMS_OUTPUT.PUT_LINE('nameï¼'||v_name);
END;
-------IN OUT
---å建åå¨è¿ç¨
create or replace procedure test_paramINOUT(p_phonenumber in out varchar2)
as
begin
p_phonenumber:='-'||p_phonenumber;
end;
----
DECLARE
p_phonenumber VARCHAR2();
BEGIN
p_phonenumber:='';
test_paramINOUT(p_phonenumber);
DBMS_OUTPUT.PUT_LINE('æ°ççµè¯å·ç ï¼'||p_phonenumber);
END;
-----sqlå½ä»¤ä¸ï¼æ¥è¯¢å½åç¨æ·çåå¨è¿ç¨æå½æ°çæºä»£ç ï¼
-----å¯ä»¥éè¿å¯¹USER_SOURCEæ°æ®åå ¸è§å¾çæ¥è¯¢å¾å°ãUSER_SOURCEçç»æå¦ä¸ï¼
SQL> DESCRIBE USER_SOURCE ;
Name Type Nullable Default Comments
---- -------------- -------- -------
-------------------------------------------------------------------------------------------------------------
NAME VARCHAR2() Y Name of the object
TYPE VARCHAR2() Y Type of the object: "TYPE", "TYPE BODY", "PROCEDURE", "FUNCTION",
"PACKAGE", "PACKAGE BODY" or "JAVA SOURCE"
LINE NUMBER Y Line number of this line of
source
TEXT VARCHAR2() Y Source text
SQL>
---æ¥è¯¢åºåå¨è¿ç¨çå®ä¹è¯å¥
select text from user_source WHERE NAME='TEST_COUNT';
----æ¥è¯¢åå¨è¿ç¨test_paramINOUTçåæ°
SQL> DESCRIBE test_paramINOUT;
Parameter Type Mode Default?
------------- -------- ------ --------
P_PHONENUMBER VARCHAR2 IN OUT
SQL>
---æ¥çå½åçåå¨è¿ç¨çç¶ææ¯å¦æ£ç¡®ï¼
---VALID为æ£ç¡®ï¼INVALID表示åå¨è¿ç¨æ ææéè¦éæ°ç¼è¯
SELECT STATUS FROM USER_OBJECTS WHERE OBJECT_NAME='TEST_COUNT';
-----å¦æè¦æ£æ¥åå¨è¿ç¨æå½æ°çä¾èµæ§ï¼å¯ä»¥éè¿æ¥è¯¢æ°æ®åå ¸USER_DENPENDENCIESæ¥ç¡®å®ï¼è¯¥è¡¨ç»æå¦ä¸ï¼
SQL> DESCRIBE USER_DEPENDENCIES;
Name Type Nullable Default Comments
-------------------- ------------- -------- ------- ----------------------------------------------------------
NAME VARCHAR2() Name of the object
TYPE VARCHAR2() Y Type of the object
REFERENCED_OWNER VARCHAR2() Y Owner of referenced object (remote owner if remote object)
REFERENCED_NAME VARCHAR2() Y Name of referenced object
REFERENCED_TYPE VARCHAR2() Y Type of referenced object
REFERENCED_LINK_NAME VARCHAR2() Y Name of dblink if this is a remote object
SCHEMAID NUMBER Y
DEPENDENCY_TYPE VARCHAR2(4) Y
SQL>
---æ¥è¯¢åå¨è¿ç¨TEST_COUNTçä¾èµå ³ç³»
SELECT REFERENCED_NAME,REFERENCED_TYPE FROM USER_DEPENDENCIES WHERE NAME='TEST_COUNT';
码上去学:C++从入门到进阶的系列书籍推荐!
要多读书,读好书!在学习编程的过程中,反复阅读书籍能带来新的收获,尤其在工作年限和经验积累之后,对内容的理解会更加深刻。下面将为您推荐C++从入门到进阶需要阅读的一些经典书籍。
首先,C++的入门阶段,需要打好C语言的基础。
1.1《C语言程序设计》(谭浩强著):这本书是学习C语言程序设计的优秀教材,被全国大多数高校选用,是学习C语言的主流用书。内容通俗易懂,是初学者的必备书籍。在排查编译问题时,翻阅相关章节,精准的文字表述让人豁然开朗,很多学生时代难以理解的内容,在工作后有了更深刻的理解。
1.2《C++ Primer 中文版(第5版)》:这是学习C++语言最经典的入门教材,详细讲解了C++语言的基础语法和概念。最新第5版全面采用C++标准,体现了C++语言的重大进展。丰富的教学辅助内容、醒目的知识点提示以及精心组织的编程示范,使得本书在C++领域权威性更加强大。无论是初学者还是中高级程序员,本书都是首选。
接下来,学习C++应用开发阶段,可以关注以下书籍。
2.1《VC++深入详解》(孙鑫著):本书是学习Windows编程的入门经典教材,从实际应用出发,深入浅出地讲述Windows程序内部运行机制、MFC框架、文本、菜单、对话框、文件操作、网络编程、进程间通信、ActiveX控件、动态链接库、HOOK编程等多个主题。
2.2《深入浅出MFC》(侯捷著):本书是学习MFC编程的经典教材,分为四大篇。从学习MFC程序设计的基础知识到掌握Visual C++开发环境,再到深入理解MFC框架的骨干程序,最后以微软公司提供的范例程序Scribble为主线,深入讲解Runtime Type Information (RTTI)、Dynamic Creation、Persistence (Serialization)、message Mapping、Command Routing等核心技术。
随后,C++的进阶阶段,推荐以下书籍。
3.1《Effective C++:改善程序与设计的个具体做法》(Scott Meyers著):本书被誉为C++程序员的必读书籍,世界顶级C++大师Scott Meyers的成名之作,读过此书将极大提升C++编程功力。
3.2《More Effective C++:个改善编程与设计的有效方法》:这是Scott Meyers的Effective系列书籍之一,是Effective C++的进阶版本,深入理解C++编译器如何解释代码,才能写出健壮的软件。
3.3《STL源码剖析》(侯捷著):本书详细讲解了STL在各种C++项目中的应用,深入剖析了vector、list、heap、deque、Red Black tree、hash table、set/map的实现,以及各种算法(排序、查找、排列组合、数据移动与复制技术)的实现。
此外,掌握Windows编程,推荐以下书籍。
4.1《Win多线程程序设计》(Jim Beveridge/Robert Wiener著):本书详细讲解了Windows系统中的多线程编程技术,分为三篇,涵盖线程的启动、结束、核心对象、同步机制等。
4.2《Windows核心编程》(Jeffrey Richter/christophe Nasarre著):本书是Windows核心编程的经典指南,深入理解Windows特性,适合Windows开发人员使用,全面修订第5版针对Windows XP、Vista和Server 进行了内容更新。
对于Linux系统学习,推荐以下书籍。
5.1《鸟哥的Unix私房菜》:本书是Linux入门书籍,系统地介绍了Unix系统起源、文件系统、命令、Shell脚本、系统安全、系统特性等内容,适合初学者。
5.2《Linux内核源代码情景分析》:本书采用情景会话教学方法,全面深入剖析Linux核心源代码,对Linux的独特优点和改进点进行评述。
在汇编与软件调试方面,推荐以下书籍。
6.1《汇编语言》(王爽著):本书是汇编语言学习者的必备宝典,采用全新结构组织内容,深入讲解汇编语言的关键环节。
6.2《IDA Pro权威指南》(Chris Eagle著):本书介绍了应用广泛的静态反汇编工具IDA Pro的使用方法,给出大量图例和C代码实例,帮助读者掌握TCP/IP的实现。
在设计模式、数据结构与算法方面,推荐以下书籍。
8.1《boost程序库完全开发指南》(罗剑锋著):本书全面介绍了boost库的用法及其在实际开发中的应用。
8.2《大话设计模式》(程杰著):这本书通过趣味问答方式讲解设计模式,让初学者更容易理解设计原则和设计过程。
8.3《设计模式:可复用面向对象软件的基础》(Erich Gamma/Richard Helm/Ralph Johnson著):本书精选出个设计模式,总结面向对象设计的经验,并以简洁可复用的形式表达出来。
8.4《数据结构与算法分析》(Mark Allen Weiss著):本书是学习数据结构和算法的经典著作,通过C程序实现,强化了对抽象数据类型概念的理解。
8.5《算法导论》(Thomas H. Cormen著):本书全面讨论各类算法,注重严谨性和全面性,适合不同层次的读者学习。
以上书籍覆盖了从C++入门到进阶的各个阶段,无论你是初学者还是有一定经验的开发人员,都能从中找到适合自己的学习资料。希望这份推荐能帮助你进一步提升编程技能,欢迎持续关注码上去学!
2024-11-26 16:42
2024-11-26 16:38
2024-11-26 15:58
2024-11-26 15:35
2024-11-26 14:33
2024-11-26 14:27