知识分享:值得学习的C语言经典开源项目

9d2e6ff4a50ec7bbb1bec0f08f07a3d2.png

点击上方蓝字关注我,了解节气咨询

10b970716e68b3144a05cb0482218403.png

听上去有些荒谬,C语言的产生竟然源于一个失败的项目。1969年,通用电气、麻省理工学院和贝尔实验室联合创立了一个庞大的项目——Multics工程。该项目的目的是创建一个操作系统,但显然遇到了麻烦:它不但无法交付原先所承诺的快速而便捷的在线系统,甚至连一点有用的东西都没有弄出来。虽然开发小组最终勉强让Multics开动起来,但他们还是陷入了泥淖,就像IBM在OS/360上面一样。他们试图建立一个非常巨大的操作系统,能够应用于规模很小的硬件系统中。Multics成了总结工程教训的宝库,但它同时也为C语言体现“小即是美”铺平了道路。

当心灰意冷的贝尔实验室的专家们撤离Multics工程后,他们又去寻找其他任务。其中一位名叫Ken Thompson的研究人员对另一个操作系统很感兴趣,他为此好几次向贝尔管理层提议,但均遭否决。在等待官方批准时,Thompson和他的同事Dennis Ritchie自娱自乐,把Thompson的“太空旅行”软件移植到不太常用的PDP-7系统上。太空旅行软件模拟太阳系的主要星体,把它们显示在图形屏幕上,并创建了一架航天飞机,它能够飞行并降落到各个行星上。与此同时,Thompson加紧工作,为PDP-7编写了一个简易的新型操作系统。它比Multics简单得多,也轻便得多。整个系统都是用汇编语言编写的。Brian Kernighan在1970年给它取名为UNIX,自嘲地总结了从Multics中获得的那些不应该做的教训。图1-1描述了早期C、UNIX和相关硬件系统的关系。

078442bf04d077de087dc1a5c5c575a7.png

是先有C语言还是先有UNIX呢?说起这个问题,人们很容易陷入先有鸡还是先有蛋的套套中。确切地说,UNIX比C语言出现得早(这也是为什么UNIX的系统时间是从1970年1月1日起按秒计算的,它就是那时候产生的啊)。然而,我们这里讨论的不是家禽趣闻,而是编程故事。用汇编语言编写UNIX显得很笨拙,在编制数据结构时浪费了大量的时间,而且系统难以调试,理解起来也很困难。Thompson想利用高级语言的一些优点,但又不想像PL/I[1]那样效率低下,也不想碰见在Multics中曾遇到过的复杂问题。在用Fortran进行了一番简短而又不成功的尝试之后,Thompson创建了B语言,他把用于研究的语言BCPL[2]作了简化,使B的解释器能常驻于PDP-7只有8KB大小的内存中。B语言从来不曾真正成功过,因为硬件系统的内存限制,它只允许放置解释器,而不是编译器,由此产生的低效阻碍了使用B语言进行UNIX自身的系统编程。

编译器设计者的金科玉律:效率(几乎)就是一切
在编译器中,效率几乎就是一切。当然还有一些其他需要关心的东西,如有意义的错误信息、良好的文档和产品支持。但与用户需要的速度相比,这些因素就黯然失色了。编译器的效率包括两个方面:运行效率(代码的运行速度)和编译效率(产生可执行代码的速度)。除了一些开发和学习环境之外,运行效率起决定性作用。
有很多编译优化措施会延长编译时间,但却能缩短运行时间。还有一些优化措施(如清除无用代码和忽略运行时检查等)既能缩短编译时间,又能减少运行时间,同时还能减少内存的使用量。这些优化措施的不利之处在于可能无法发现程序中无效的运行结果。优化措施本身在转换代码时是非常谨慎的,但如果程序员编写了无效的代码(如:越过数组边界引用对象,因为他们“知道”附近有他们需要的变量)就可能引发错误的结果。
这就是为什么说效率几乎就是一切但也并不是绝对的道理。如果得到的结果是不正确的,那么效率再高又有什么意义呢?编译器设计者通常会提供一些编译器选项。这样,每个程序员可以选择自己想要的优化措施。B语言不算成功,而Dennis Ritchie所创造的注重效率的“New B”却获得了成功,充分证明了编译器设计者的这条金科玉律。

B语言通过省略一些特性(如嵌套过程和一些循环结构),对BCPL语言作了简化,并发扬了“引用数组元素相当于对指针加上偏移量的引用”这个想法。B语言同时保持了BCPL语言无类型这个特点,它仅有的操作数就是机器的字。Thomposon发明了++和--操作符,并把它加入到PDP-7的B编译器中。它们在C语言中依然存在,很多人天真地以为这是由于PDP-11存在对应的自动增/减地址模型,这种想法是错误的!自动增/减机制的出现早于PDP-11硬件系统的出现。尽管在C语言中,拷贝字符串中的一个字符的语句:

*p++ = *s++;

可以极其有效地被编译为PDP-11代码:

moveb (r0)+, (r1)+

这使得许多人错误地以为前者的语句形式是根据后者特意设计的。

当1970年开发平台转移到PDP-11以后,无类型语言很快就显得不合时宜了。这种处理器以硬件支持几种不同长度的数据类型为特色,而B语言无法表达不同的数据类型。效率也是一个问题,这也迫使Thompson在PDP-11上重新用汇编语言实现了UNIX。Dennis Ritchie利用PDP-11的强大性能,创立了能够同时解决多种数据类型和效率的“New B”(这个名字很快变成了“C”)语言,它采用了编译模式而不是解释模式,并引入了类型系统,每个变量在使用前必须先声明。

C语言的早期体验

增加类型系统的主要目的是帮助编译器设计者区分新型PDP-11机器所拥有的不同数据类型,如单精度浮点数、双精度浮点数和字符等。这与其他一些语言如Pascal形成了鲜明的对比。在Pascal中,类型系统的目的是保护程序员,防止他们在数据上进行无效的操作。由于设计哲学不同,C语言排斥强类型,它允许程序员需要时可以在不同类型的对象间赋值。类型系统的加入可以说是事后诸葛,从未在可用性方面进行过认真的评估和严格的测试。时至今日,许多C程序员仍然认为“强类型”只不过是增加了敲击键盘的无用功。

除了类型系统之外,C语言的许多其他特性是为了方便编译器设计者而建立的(为什么不呢?开始几年C语言的主要客户就是那些编译器设计者啊)。根据编译器设计者的思路而发展形成的语言特性有:

  • 数组下标从0而不是1开始。绝大多数人习惯从1而不是0开始计数。编译器设计者则选择从0开始,因为偏移量的概念在他们心中已是根深蒂固。但这种设计让一般人感觉很别扭。尽管我们定义了一个数组a[100],你可千万别往a[100]里存储数据,因为这个数组的合法范围是从a[0]到a[99]。

  • C语言的基本数据类型直接与底层硬件相对应。例如,不像Fortran,C语言中不存在内置的复数类型。某种语言要素如果底层硬件没有提供直接的支持,那么编译器设计者就不会在它上面浪费任何精力。C语言一开始并不支持浮点类型,直到硬件系统能够直接支持浮点数之后才增加了对它的支持。

  • auto关键字显然是摆设。这个关键字只对创建符号表入口的编译器设计者有意义。它的意思是“在进入程序块时自动进行内存分配”(与全局静态分配或在堆上动态分配相反)。其他程序员不必操心auto这个关键字,它是缺省的变量内存分配模式。

  • 表达式中的数组名可以看作是指针。把数组当作指针,简化了很多东西。我们不再需要一种复杂的机制区分它们,把它们传递到一个函数时不必忍受必须复制所有数组内容的低效率。不过,数组和指针并不是在任何情况下都是等效的,更详细的讨论参见第4章。

  • float被自动扩展为double。尽管在ANSI C中情况不再如此,但最初浮点数常量的精度都是double型的,所有表达式中float变量总被自动转换成double。这样做的理由从未公诸于众,但它与PDP-11中浮点数的硬件表示方式有关。首先,在PDP-11或VAX中,从float转换到double代价非常小,只要在后面增加一个每个位均为0的字即可。如果要转换回来,去掉第二个字就可以了。其次,要知道在某些PDP-11的浮点数硬件表示形式中有一个运算模式位(mode bit),你可以只进行float的运算,也可以只进行double的运算,但如果想在这两种方式间进行切换,就必须修改这个位来改变运算模式。在早期的UNIX程序中,float用得不是太多,所以把运算模式固定为double 是比较方便的,省得编译器设计者去跟踪它的变化。

  • 不允许嵌套函数(函数内部包含另一个函数的定义)。这简化了编译器,并稍微提高了C程序的运行时组织结构。具体的机理在第6章“运动的诗章:运行时数据结构”中详细描述。

  • register关键字。这个关键字能给编译器设计者提供线索,就是程序中的哪些变量属于热门(经常被使用),这样就可以把它们存放到寄存器中。这个设计可以说是一个失误,如果让编译器在使用各个变量时自动处理寄存器的分配工作,显然比一经声明就把这类变量在生命期内始终保留在寄存器里要好。使用register关键字,简化了编译器,却把包袱丢给了程序员。

为了C编译器设计者的方便而建立的其他语言特性还有很多。这本身不是一件坏事,它大大简化了C语言本身,而且通过回避一些复杂的语言要素(如Ada中的泛型和任务,PL/I中的字符串处理,C++中的模板和多重继承),C语言更容易学习和实现,而且效率非常高。

和其他大多数语言不同,C语言有一个漫长的进化过程。在目前这个形式之前,它经历了许多中间状态。它历经多年,从一个实用工具进化为一种经过大量试验和测试的语言。第一个C编译器大约出现在1970年,距今20多年了[3]。时光荏苒,作为它的根基的UNIX系统得到了广泛使用,C语言也随之茁壮成长。它对直接由硬件支持的底层操作的强调,带来了极高的效率和移植性,反过来也帮助UNIX获得了巨大的成功。

K&R C

到了20世纪70年代中期,C语言已经很接近目前这种我们所知道和喜爱的形式了。更多的改进仍然存在,但大部分都只是一些细节的变化(比如允许函数返回结构值)和一些对基本类型进行扩展以适应新的硬件变化的改进。(比如增加关键字unsigned和long)。1978年,Steve Johnson编写了pcc这个可移植的C编译器。它的源代码对贝尔实验室之外开放,并被广泛移植,形成了整整一代C编译器的基础。C语言的演化之路如图1-2所示。

ff755c6b1ccd9c71e72e23da98963ec6.png

图1-2 后期的C

软件信条一个非比寻常的Bug
C语言从Algol-68中继承了一个特性,就是复合赋值符。它允许对一个重复出现的操作数只写一次而不是两次,给代码生成器一个提示,即操作数寻址也可以类似地紧凑。这方面的一个例子是用b+=3作为b=b+3的缩写。复合赋值符最初的写法是先写赋值符,再写操作符,就像:b=+3。在B语言的词法分析器里有一个技巧,使实现=op这种形式要比实现目前所使用的op=形式更简单一些。但这种形式会引起混淆,它很容易把
b=-3; /* 从b中减去3 */

b= -3; /* 把-3赋给b */
搞混淆。
因此,这个特性被修改为目前所使用的这种形式。作为修改的一部分,代码格式器程序indent也作了相应修改,用于确定复合赋值符的过时形式,并交换两者的位置,把它转换为对应的标准形式。这是个非常糟糕的决定,任何格式器都不应该修改程序中除空白之外的任何东西。令人不快的是,这种做法会引入一个Bug,就是几乎任何东西(只要不是变量),如果它出现在赋值符后面,就会与赋值符交换位置。
如果你运气好,这个Bug可能会引起语法错误,如:
epsilon=.0001;
会被交换成:
epsilon.=0001;
这条语句将无法通过编译器,你马上就能发现错误。但一条源语句也可能是这样的:
valve=!open; /*valve被设置为open的逻辑反*/
会悄无声息地交换成:
valve!=open; /*valve与open进行不相等比较*/
这条语句同样能够通过编译,但它的作用与源语句明显不同,它并不改变valve的值。
在后面这种情况下,这个Bug会潜伏下来,并不会被马上检测到。在赋值后面加个空格是很自然的事,所以随着复合赋值符的过时形式越来越罕见,人们也逐渐忘记了indent程序曾经被用于“改进”这种过时的形式。这个由indent程序引起的 Bug直到20世纪80年代中期才在各种C编译器中销声匿迹。这是一个应被坚决摒弃的东西!

1978年,C语言经典名著The C Programming Language出版了。这本书受到了广泛的赞誉,其作者Brian Kernighan和Dennis Ritchie也因此名声大噪,所以这个版本的C语言就被称为“K&R C”。出版商最初估计这本书将售出1000册左右。截止到1994年,这本书大约售出了150万册(参见图1-3)。C语言成为最近20年最成功的编程语言之一,可能就是最成功的。但随着C语言的广泛流行,许多人试图从C语言中产生其他变种。

10ab6140611494c04c7ec28d15153b55.png

图1-3 像猫王艾尔维斯一样,C语言无处不在

UNIX系统

由于C语言因UNIX系统而生,也因此而流行,所以我们从UNIX系统开始(注意:我们提到的UNIX还包含其他系统,如FreeBSD,它是UNIX的一个分支,但是由于法律原因不使用该名称)。

1.在UNIX系统上编辑

UNIX C没有自己的编辑器,但是可以使用通用的UNIX编辑器,如emacs、jove、vi或X Window System文本编辑器。

作为程序员,要负责输入正确的程序和为储存该程序的文件起一个合适的文件名。如前所述,文件名应该以.c结尾。注意,UNIX区分大小写。因此,budget.c、BUDGET.c和Budget.c是3个不同但都有效的C源文件名。但是BUDGET.C是无效文件名,因为该名称的扩展名使用了大写C而不是小写c。

假设我们在vi编译器中编写了下面的程序,并将其储存在inform.c文件中:

#include <stdio.h>
int main(void)
{printf("A .c is used to end a C program filename.\n");return 0;
}

以上文本就是源代码,inform.c是源文件。注意,源文件是整个编译过程的开始,不是结束。

2.在UNIX系统上编译

虽然在我们看来,程序完美无缺,但是对计算机而言,这是一堆乱码。计算机不明白#include和printf是什么(也许你现在也不明白,但是学到后面就会明白,而计算机却不会)。如前所述,我们需要编译器将我们编写的代码(源代码)翻译成计算机能看懂的代码(机器代码)。最后生成的可执行文件中包含计算机要完成任务所需的所有机器代码。

以前,UNIX C编译器要调用语言定义的cc命令。但是,它没有跟上标准发展的脚步,已经退出了历史舞台。但是,UNIX系统提供的C编译器通常来自一些其他源,然后以cc命令作为编译器的别名。因此,虽然在不同的系统中会调用不同的编译器,但用户仍可以继续使用相同的命令。

编译inform.c,要输入以下命令:

cc inform.c

几秒钟后,会返回UNIX的提示,告诉用户任务已完成。如果程序编写错误,你可能会看到警告或错误消息,但我们先假设编写的程序完全正确(如果编译器报告void的错误,说明你的系统未更新成ANSI C编译器,只需删除void即可)。如果使用ls命令列出文件,会发现有一个a.out文件(见图1.5)。该文件是包含已翻译(或已编译)程序的可执行文件。要运行该文件,只需输入:

a.out

输出内容如下:

A .c is used to end a C program filename.

b21ec53ae477519308f1c9bdf1333a76.png

图1.5 用UNIX准备C程序

如果要储存可执行文件(a.out),应该把它重命名。否则,该文件会被下一次编译程序时生成的新a.out文件替换。

如何处理目标代码?C编译器会创建一个与源代码基本名相同的目标代码文件,但是其扩展名是.o。在该例中,目标代码文件是inform.o。然而,却找不到这个文件,因为一旦链接器生成了完整的可执行程序,就会将其删除。如果原始程序有多个源代码文件,则保留目标代码文件。学到后面多文件程序时,你会明白到这样做的好处。

Linux系统

Linux是一个开源、流行、类似于UNIX的操作系统,可在不同平台(包括PC和Mac)上运行。在Linux中准备C程序与在UNIX系统中几乎一样,不同的是要使用GNU提供的GCC公共域C编译器。编译命令类似于:

gcc inform.c

注意,在安装Linux时,可选择是否安装GCC。如果之前没有安装GCC,则必须安装。通常,安装过程会将cc作为gcc的别名,因此可以在命令行中使用cc来代替gcc。

613c78d4492b913728e605a548aa555d.png

END

*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

93727ab72571f030412486402277f5c7.png

5eb777692a80d685698034468a6c9e7a.gif

戳“阅读原文”我们一起进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle idm_批准Oracle IDM中的特定Web服务

oracle idm关于Web服务端点的快速发布&#xff0c;OIM和SOA在与批准有关的场景中使用了Web服务端点- 基本内容&#xff0c;但对于初学者可能有用 。 Oracle IDM与SOA套件集成并利用其提供与批准相关的功能&#xff08;说实话&#xff0c;SOA非常丰富&#xff0c;并且也被用作W…

C语言编程笔记:关于 for循环 的那些不为人知的秘密

点击上方蓝字关注我&#xff0c;了解更多咨询好吧&#xff0c;也许你认为我在写一篇如何使用for循环的文章&#xff0c;&#xff0c;&#xff0c;&#xff0c;首先&#xff0c;我想说无论是学习C语言还是学习java的同学都能从此文中获益&#xff0c;还有&#xff0c;你确定你会…

weld焊接_玩Weld-Probe –一站式查看CDI的所有方面

weld焊接当我坐在DevConf.CZ的会议室时&#xff0c; Weld 3.0.0.Alpha4已发布 。 大约在Jozef Hartinger&#xff08; jozefhartinger &#xff09;旁边或多或少 &#xff0c;后者在共享休息前几分钟告诉我有关此最新版本的新功能的信息。 有一个特别的功能真正引起了我的注意&…

C语言:一种通用的程序设计语言

点击上方蓝字关注我&#xff0c;了解更多咨询语言是一种通用的程序设计语言。它同UNIX系统之间具有非常密切的关系。C语言是在UNIX系统上开发的&#xff0c;且无论是UNIX系统本身还是其上运行的大部分程序&#xff0c;都是C语言编写的。但是C语言并不受限于任何一种操作系统或机…

可禁用计算机服务,win10哪些服务可以禁用 服务哪些可以禁止启动

win10服务哪些可以禁止启动&#xff1f;方法一&#xff1a;命令方法首先使用 Windows R 组合快捷键打开“运行”窗口&#xff0c;之后键入 services.msc 按下回车键&#xff0c;即可打开“服务”。方法二&#xff1a;快捷方式法在Win10桌面的“此电脑”图标上点击鼠标右键&…

如何用最短的时间学会C语言,并掌握C语言的精髓所在?

点击上方蓝字关注我&#xff0c;了解更多咨询及C语言&#xff0c;我想凡是学过它的朋友都有这样一种感觉&#xff0c;那就是“让我欢喜让我忧。”欢喜的是&#xff0c;C语言功能非常强大、应用广泛&#xff0c;一旦掌握了后&#xff0c;你就可以理直气壮地对他人说“我是电脑高…

apache fop_Apache FOP与Eclipse和OSGi的集成

apache fopApache FOP是由XSL格式化对象&#xff08; XSL-FO &#xff09;驱动的开源打印处理器。 例如&#xff0c;将数据对象转换为PDF可能非常有用。 但是&#xff0c;事实证明&#xff0c;将其集成到PDE中并最终以OSGi Service的形式启动和运行有点麻烦。 因此&#xff0c…

2022年最值得学习的 5 种编程语言,你有在学习吗?

点击上方蓝字关注我&#xff0c;了解更多咨询作为一个初学者电脑程序员&#xff0c;很多人都会想知道当下主流的编程语言有哪些&#xff0c;哪些行业和公司都在用它们&#xff0c;因为这些信息可以帮助你了解想要学习的内容&#xff0c;使你更接近最终想用代码完成的事情。今天…

wildfly mysql_MySQL作为Kubernetes服务,可从WildFly Pod访问

wildfly mysqlKubernetes上使用Vagrant的Java EE 7和WildFly&#xff08;技术提示&#xff03;71&#xff09;介绍了如何在使用Kubernetes和Docker托管的WildFly上运行琐碎的Java EE 7应用程序。 Java EE 7应用程序是在世界范围内交付的动手实验室 。 它使用与WildFly捆绑在一起…

想学C语言?这些你一定要知道

点击上方蓝字关注我&#xff0c;了解更多咨询首先&#xff0c;你想运行自己的C语言程序&#xff0c;就必须要有一个IDE&#xff08;集成式开发工具&#xff09;。不然想运行程序很难。这里有两个方法可以运行你的C语言程序&#xff0c;一个是在菜鸟网站上云运行C语言程序&#…

mongodb实验报告_Dropwizard,MongoDB和Gradle实验

mongodb实验报告介绍 我使用Dropwizard&#xff0c;MongoDB和Gradle创建了一个小项目。 它实际上是作为一个实验性的Guava缓存开始的&#xff0c;作为将计数器发送到MongoDB&#xff08;或任何其他DB&#xff09;的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来&#xff0…

历城职专学前计算机专业,历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕...

原标题&#xff1a;历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕技能运动会学前教育专业技能运动会1月13日&#xff0c;历城职专学前教育专业2020学年第一学期技能运动会拉开帷幕&#xff0c;技能运动会是历城职专对每一位职专学子专业技能考核的一项重要检测&…

如何正确认识C语言在当今编程领域的地位

点击上方蓝字关注我&#xff0c;了解更多咨询一、什么是语言&#xff0c;什么是C语言&#xff0c;有什么区别与联系&#xff1f;一提到语言这个词&#xff0c;人们自然想到的是像英语、汉语等这样的自然语言&#xff0c;因为它是人和人相互交流信息不可缺少的工具。大家听到我们…

理解好内存管理,C语言就不难学了

点击上方蓝字关注我&#xff0c;了解更多咨询任何程序运行起来都需要分配内存空间存放该进程的资源信息的&#xff0c;C程序也不例外。C程序中的变量、常量、函数、代码等等的信息所存放的区域都有所不同&#xff0c;不同的区域又有不同的特性。C语言学习者、尤其是在学习嵌入式…

智伴机器人安卓怎么设置个人热点_周五到!!宿舍断网怎么办,教你一招

对于大学里喜欢上网的小伙伴们&#xff0c;一旦到了断网的时间段&#xff0c;非常的难受&#xff0c;今天小白教大家一招&#xff0c;看到最后&#xff01;&#xff01;以后断网再也不怕啦&#xff0c;熬夜伤身&#xff0c;慎用&#xff01;&#xff01;相信很多同学都知道了手…

计算机用户guest无法删除吗,Win7怎么删除Guest账户?

原标题&#xff1a;Win7怎么删除Guest账户&#xff1f;我们都知道&#xff0c;访客帐户是系统附带的帐户。通常&#xff0c;用户给出了访客帐户。为了确保系统的安全性&#xff0c;它是一个限制帐户。使用客人帐户&#xff0c;您有权临时使用我们的计算机。但是&#xff0c;一些…

为什么C语言不会过时?

点击上方蓝字关注我&#xff0c;了解更多咨询评价任何一门编程语言&#xff0c;都是招人骂的。永远是这样。就像是春寒料峭的季节&#xff0c; 街上穿棉袄和穿单衣的擦肩而过&#xff0c;双方一定是同时在心里出现了两个字&#xff1a;“傻逼&#xff01;”这个在心理学上有个专…

机械装备计算机控制技术考试题,武汉理工大学机电工程学院研究生课程考试试题(肖峻)...

武汉理工大学机电工程学院研究生课程考试试题课程名称 机械装备计算机控制技术Ⅱ一&#xff0e;简答题(合计30分&#xff0c;每题10分)1、计算机控制系统按系统结构和控制功能分为哪几种&#xff1f;分别描述其特点。2、简述几种常用的数字滤波方法及其优、缺点。如何选用各种数…

java 性能 优化_Java十大简单性能优化

java 性能 优化关于“ web scale ”这个流行词有很多炒作&#xff0c;人们花了很多时间来重新组织他们的应用程序体系结构&#xff0c;以使其系统“规模化”。 但是什么是扩展&#xff0c;我们如何确保可以扩展&#xff1f; 缩放的不同方面 上面提到的炒作主要是关于扩展负载…

cx_oracle写日志信息_看日志痛苦——可能是你方法不对

看日志&#xff0c;是研发的日常工作&#xff0c;相信你已经从各种报错日志中查出许多BUG&#xff0c;但也被冗长、复杂的日志困扰过无数次。在日常工作中&#xff0c;我也经常痛苦于看日志&#xff0c;一般是这些日志长得面目狰狞&#xff1a;日志文件太大&#xff0c;打开都很…