要成为一个CC++程序员要学哪些东西

要成为一个CC++程序员要学哪些东西,第1张

1语言
我们要成为一个程序员,学的东西会很多很杂,但是最开始一定要从语言开始学习,而学习语言最关键的莫过于选好一本书,学校的教材就算了,根本没有写 得好的。在此隆重推荐《C++ Primer》,这本书很厚,内容也很丰富,对知识的讲解不仅仅停留在表面。如果这本书能有耐心看完,语言方面基本就没有什么大问题了,对以后的学习也打 下了一个很好的基础。
2GUI
C++方面的GUI库有很多种,比如MFC、WTL、wxWidgets、QT。这些GUI库都各有自己的特点,其实我们只要先了解一种就可以了, 只要深入了解了一种GUI库,需要的时候再学习其他的就够了,本质上都差不多,很快就可以上手了。MFC虽然设计上有很多问题,但是作为入门还是不错的, 而且学习资料很多,碰到问题也好解决。
3数据结构和算法
很多人都忽视了数据结构和算法方面的知识,尤其是一些编程语言的库做得非常好,几乎不需要自己去实现一些数据结构和算法,导致现在很多程序员不重视 甚至忽略这方面的知识。但是,当我们想让我们的程序跑的更快、内存占用更少的时候,这些知识就非常非常重要了。很多程序员都是刚开始的时候不重视这些,但 是工作几年后又来补习这些知识。
最开始可能不需要学习的太深入,但是基本的数据结构和算法一定要知道。
推荐《数据结构(C语言版)》,在数据结构和算法的学习中,最好不要去关心面向对象方面的技巧,就用C语言来实现,这样能更关注于算法本身的内容。
4数据库
学习数据库的基础知识,并且掌握一种数据库使用,推荐使用mysql,而且最好不要用一些封装好的接口,而应该直接用mysql提供的数据库api,可能对数据库了解的会更深入。
5并行
cpu主频已经不能遵循摩尔定律了,现在cpu发展的趋势是多核心。无论是多线程,还是多进程,都是为了更好的利用cpu的性能,提供更好的用户体验。这就要求我们如果要写出高效的应用程序,必然要涉及到并行计算。多花些精力在并行计算上吧,一定会有丰富的回报。
6网络编程
这里所指的网络编程是指socket编程。现在C++的应用很多都是在做服务器开发,如何开发一个高并发、大吞吐量、高稳定性的服务器就是我们要考虑的了。
7设计模式
设计模式不是具体的技术,更多的是如何让代码更容易阅读、更好扩展、更容易使用。
8库的使用
C++标准库仅仅提供了一些很基本的功能,所以我们经常会引入一些第三方库。最著名的恐怕就是被称为准标准库的boost库,它提供了我们编程中用 到的各方面的技术,文本处理、算法、网络、多线程、图像处理等等,几乎无所不包。其它也有一些专著于某一方面的库,比如ACE是网络通信方面 的,TinyXML是解析xml的,OGRE是图形渲染方面的。
9 *** 作系统的知识
程序员需要了解的 *** 作系统知识和普通用户是不一样的,一个高手是需要深入了解 *** 作系统的方方面面,而不是停留在使用层面。至于应该了解哪些知 识,windows上的去看《windows核心编程》,linux的去看《深入理解linux内核》,应该可以知道自己应该学什么了。

socket接受线程:C语言为了高并发所以选择了epoll。当程序启动的时候(g_net_updatec文件中main函数,会启动一个thread见函数create_accept_task)这个thread就处理一件事情,只管接收客户端的连接,当有连接进来的时候 通过epoll_ctl函数,把socket fd 加入到epoll里面去,epoll设置监听事件EPOLLIN | EPOLLET; 主要是监听的是加入到epoll中的socket是否可读(因为我的需求是客户端连上了server就会马上向server发送一份数据的)。其它的部分在主线程中处理。

主线程:是一个无线循环,epoll_wait 函数相当于把客户端的连接从epoll中拿出来(因为我们监听的是EPOLLIN | EPOLLET)说明这个时候客户端有数据发送过来)。再通过recv_buffer_from_fd 函数把客户端发送过来的数据读出来。然后其他的一切就抛给线程池去处理。

线程池:(代码中我会在池里面创建15个线程) 双向链表。加入线程就是在链表后面加一个链表项,链表的前面会一个一个被拿出来处理。主要是malloc 函数free函数,sem_wait函数sem_post的处理(sem_wait 会阻塞当值大于0是会减一,sem_post是值加一)。typedef void (FUNC)(void arg, int index);是我们自定义的线程的逻辑处理部分,arg是参数,index是第几个线程处理(我们隐形的给每个线程都标了号),例如代码中的respons_stb_info,更加具体可以看看代码里面是怎么实现的。聪明的你也可以改掉这块的内容改成动态线程池,当某个时刻的处理比较多的时候能够动态的增加线程,而不像我代码里面的是固定的。

数据库连接池:按照我的需求在处理客户端请求数据的时候是要访问数据库的。就是一下子创建出一堆的数据连接。要访问数据库的时候先去数据库连接池中找出空闲的连接,具体可以看下代码。使用的时候可以参考下database_processc文件(代码中数据库连接池和线程池中的个数是一样的)。这里我想说下get_db_connect_from_pool这个函数,我用了随机数,我是为了不想每次都从0开始去判断哪个连接没有用到。为了数据库连接池中的每个链接都能等概率的使用到,具体的还是可以看下代码的实现。

服务程序最为关键的设计是并发服务模型,当前有以下几种典型的模型:
- 单进程服务,使用非阻塞IO
使用一个进程服务多个客户,通常与客户通信的套接字设置为非阻塞的,阻塞只发生在select()、poll()、epoll_wait()等系统调用上面。这是一种行之有效的单进程状态机式服务方式,已被广泛采用。
缺点是它无法利用SMP(对称多处理器)的优势,除非启动多个进程。此外,它尝试就绪的IO文件描述符后,立即从系统调用返回,这会导致大量的系统调用发生,尤其是在较慢的字节传输时。
select()本身的实现也是有局限的:能打开的文件描述符最多不能超过FD_SETSIZE,很容易耗尽;每次从select()返回的描述符组中扫描就绪的描述符需要时间,如果就绪的描述符在末尾时更是如此(epoll特别彻底修复了这个问题)。
- 多进程服务,使用阻塞IO
也称作 accept/fork 模型,每当有客户连线时产生一个新的进程为之服务。这种方式有时是必要的,比如可以通过 *** 作系统获得良好的内存保护,可以以不同的用户身份运行程序,可以让服务运行在不同的目录下面。但是它的缺点也很明显:进程比较占资源,进程切换开销太大,共享某些信息比较麻烦。Apache 13就使用了这种模型,MaxClients数很容易就可以达到。
- 多线程服务,使用阻塞IO
也称之 accept/pthread_create模型,有新客户来时创建一个服务线程而不是服务进程。这解决了多进程服务的一些问题,比如它占用资源少,信息共享方便。但是麻烦在于线程仍有可能消耗光,线程切换也需要开销。
- 混合服务方式
所谓的混合服务方式,以打破服务方和客户方之间严格的1:1关系。基本做法是:
新客户到来时创建新的工作线程,当该工作线程检测到网络IO会有延迟时停止处理过程,返回给Server一个延迟处理状态,同时告诉 Server被延迟的文件描述符,延迟超时时间。Server会在合适的时候返回工作线程继续处理。注意这里的工作线程不是通过 pthread_create()创建的,而是被包装在专门用于处理延迟工作的函数里。
这里还有一个问题,工作线程如何检测网络IO会有延迟?方法有很多,比如设置较短的超时时间调用poll(),或者甚至使用非阻塞IO。如果是套接字,可以设置SO_RCVTIMEO和SO_SNDTIMEO选项,这样更有效率。
除了延迟线程,Server还应提供了未完成线程的支持。
如有有特别耗费时间的 *** 作,你可以在完成部分工作后停止处理,返回给Server一个未完成状态。这样Server会检查工作队列是否有别的线程,如果有则让它们运行,否则让该工作线程继续处理,这可以防止某些线程挨饿。
典型的一个混合服务模型开源实现ServerKit
Serverkit的这些线程支持功能可简化我们的服务程序设计,效率上应该也是有保证的。
2 队列(queue)
ServerKit提供的队列是一个单向链表,队列的存取是原子 *** 作,如果只有一个执行单元建议不要用,因为原子 *** 作的开销较大。
3 堆(heap)
malloc()分配内存有一定的局限,比如在多线程的环境里,需要序列化内存分配 *** 作。ServerKit提供的堆管理函数,可快速分配内存,可有效减少分配内存的序列化 *** 作,堆的大小可动态增长,堆有引用计数,这些特征比较适合多线程环境。目前ServerKit堆的最大局限是分配单元必须是固定大小。
4 日志记录
日志被保存在队列,有一个专门的线程处理队列中的日志记录:它或者调用syslog()写进系统日志,或者通过UDP直接写到远程机器。后者更有效。
5 读写锁
GNU libc也在pthreads库里实现了读写锁,如果定义了__USE_UNIX98就可以使用。不过ServerKit还提供了读写锁互相转换的函数,这使得锁的应用更为d性。比如拥有读锁的若干个线程对同一个hash表进行检索,其中一个线程检索到了数据,此时需要修改它,一种办法是获取写锁,但这会导致释放读锁和获取写锁之间存在时间窗,另一种办法是使用ServerKit提供的函数把读锁转换成写锁,无疑这种方式更有效率。
除了以上这些功能,ServerKit还提供了数据库连接池的管理(当前只支持MySQL)和序列化(Sequences),如感兴趣可参见相关的API文档。
二、ServerKit服务模块编写
ServerKit由3部分组成:server程序,负责加载服务模块、解析配置文件、建立数据库连接池;libserver,动态链接库,提供所有功能的库支持,包括server本身也是调用这个库写的;API,编程接口,你编写的服务模块和ServerKit框架进行对话的接口。
ServerKit需要libConfuse解析配置文件,所以出了安装ServerKit,还需要安装libConfuse。关于libConfuse可参考 >服务器开发的数据逻辑是指服务器端对于客户端请求所做出的响应,包括如何处理和存储数据、如何验证用户身份、如何保证数据安全等方面。
具体来说,服务器开发的数据逻辑通常包括以下几个方面:
1 数据库设计:根据业务需求设计数据库结构,并确定表之间的关系。这涉及到选择合适的数据库类型、建立索引以提高查询效率等问题。
2 数据 *** 作:编写代码实现对数据库中数据进行增删改查等基本 *** 作。同时需要考虑并发访问时可能产生的冲突问题,并采取相应措施解决。
3 用户认证与权限管理:确保只有经过身份验证且有权限访问特定资源的用户才能够进行相关 *** 作。这需要在服务器端实现用户登录、注册和密码找回功能,并设置不同级别或角色的用户可以执行哪些 *** 作。
4 数据安全性:确保敏感信息得到充分加密和保护,防止恶意攻击者通过各种手段获取机密信息。这需要使用一些加密算法或协议来确保传输过程中信息不被窃听或篡改,并采用其他技术手段(例如防火墙)来增强系统安全性。
5 性能优化:针对大规模数据处理和高并发访问等场景,对服务器端代码进行优化以提高系统性能。这包括使用缓存技术、负载均衡等手段来减轻服务器压力,并采用异步编程模型来提高响应速度。
综上所述,服务器开发的数据逻辑是一个复杂而又关键的领域,在实际开发中需要充分考虑各种因素,并不断优化和改进系统设计与实现。

所谓并发服务器就是在同一个时刻可以处理来自多个客户端的请求;循环服务器是指服务器在同一时刻只可以响应一个客户端的请求。而且对于TCP和UDP套接字,这两种服务器的实现方式也有不同的特点。
1、TCP循环服务器:
首先TCP服务器接受一个客户端的连接请求,处理连接请求,在完成这个客户端的所有请求后断开连接,然后再接受下一个客户端的请求。创建TCP循环服务器的算法如下:
复制代码 代码如下:
socket(……); //创建一个TCP套接字
bind(……); //邦定公认的端口号
listen(……); //倾听客户端连接
while(1) //开始循环接收客户端连接
{
accept(……);//接收当前客户端的连接
while(1)
{ //处理当前客户端的请求
read(……);
process(……);
write(……);
}
close(……); //关闭当前客户端的连接,准备接收下一个客户端连接
}
TCP循环服务器一次只处理一个客户端的请求,如果有一个客户端占用服务器不放时,其它的客户机连接请求都得不到及时的响应。因此,TCP服务器一般很少用循环服务器模型的。
2、TCP并发服务器:
并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理。创建TCP并发服务器的算法如下:
复制代码 代码如下:
socket(……); //创建一个TCP套接字
bind(……); //邦定公认的端口号
listen(……);//倾听客户端连接
while(1) //开始循环接收客户端的接收
{
accept(……);//接收一个客户端的连接
if(fork(……)==0) //创建子进程
{
while(1)
{ //子进程处理某个客户端的连接
read(……);
process(……);
write(……);
}
close(……); //关闭子进程处理的客户端连接
exit(……) ;//终止该子进程
}
close(……); //父进程关闭连接套接字描述符,准备接收下一个客户端连接
}
TCP并发服务器可以解决TCP循环服务器客户端独占服务器的情况。但同时也带来了一个不小的问题,即响应客户机的请求,服务器要创建子进程来处理,而创建子进程是一种非常消耗资源的 *** 作。
3、UDP循环服务器:
UDP服务器每次从套接字上读取一个客户端的数据报请求,处理接收到的UDP数据报,然后将结果返回给客户机。创建UDP循环服务器的算法如下:
1 socket(……); //创建一个数据报类型的套接字 2 bind(……); //邦定公认的短口号 3 while(1) //开始接收客户端的连接 4 { //接收和处理客户端的UDP数据报 5 recvfrom(……); 6 process(……); 7 sendto(……);//准备接收下一个客户机的数据报 8 }
消除行号
因为UDP是非面向连接的,没有一个客户端可以独占服务器。只要处理过程不是死循环,服务器对于每一个客户机的请求总是能够处理的。
UDP循环服务器在数据报流量过大时由于处理任务繁重可能造成客户技数据报丢失,但是因为UDP协议本身不保证数据报可靠到达,所以UDP协议是允许丢失数据报的。
鉴于以上两点,一般的UDP服务器采用循环方式4、UDP并发服务器把并发的概念应用UDP就得到了并发UDP服务器,和并发TCP服务器模型一样是创建子进程来处理的。
创建UDP并发服务器的算法如下:
复制代码 代码如下:
socket(……); //创建一个数据报类型的套接字
bind(……); //邦定公认的短口号
while(1) //开始接收客户端的连接
{ //接收和处理客户端的UDP数据报
recvfrom(……);
if(fork(……)==0) //创建子进程
{
rocess(……);
sendto(……);
}
}
除非服务器在处理客户端的请求所用的时间比较长以外,人们实际上很少用这种UDP并发服务器模型的。
4、多路复用I/O并发服务器:
创建子进程会带来系统资源的大量消耗,为了解决这个问题,采用多路复用I/O模型的并发服务器。采用select函数创建多路复用I/O模型的并发服务器的算法如下:
初始化(socket,bind,listen);
复制代码 代码如下:
while(1)
{
设置监听读写文件描述符(FD_);
调用select;
如果是倾听套接字就绪,说明一个新的连接请求建立
{
建立连接(accept);
加入到监听文件描述符中去;
}
否则说明是一个已经连接过的描述符
{
进行 *** 作(read或者write);
}
多路复用I/O可以解决资源限制问题,此模型实际上是将UDP循环模型用在了TCP上面。这也会带了一些问题,如由于服务器依次处理客户的请求,所以可能导致友的客户会等待很久。

一般来说,我们的网页代码编程都是基于一定的规则来完成编写的,而大部分的情况下我们采用也是utf的编辑规则。下面,南邵电脑培训就通过案例分析来了解一下服务器开发可以使用哪些编码规则。



服务器开发适用哪些编程开发规则

那么什么是编码什么是UTF-8

我们都知道,计算机使用0和1来存储文本。比如字符“C”被存成“01000011”,那么计算机在显示这个字符时需要经过两个步骤:

计算机读取“01000011”,得到数字67,因为67被编码成“01000011”。

计算机在Unicode字符集中查找67,找到了“C”。

同样的:

我的电脑将“C”映射成Unicode字符集中的67。

我的电脑将67编码成“01000011”,并发送给Web服务器。

几乎所有的网络应用都使用了Unicode字符集,因为没有理由使用其他字符集。

Unicode字符集包含了上百万个字符。简单的编码是UTF-32,每个字符使用32位。这样做简单,因为一直以来,计算机将32位视为数字,而计算机在行的就是处理数字。但问题是,这样太浪费空间了。

UTF-8可以节省空间,在UTF-8中,字符“C”只需要8位,一些不常用的字符,比如“”需要32位。其他的字符可能使用16位或24位。一篇类似本文这样的文章,如果使用UTF-8编码,占用的空间只有UTF-32的四分之一左右。

MySQL的“utf8”字符集与其他程序不兼容,它所谓的“”,可能真的是一坨

MySQL简史

为什么MySQL开发者会让“utf8”失效我们或许可以从提交日志中寻找答案。

MySQL从41版本开始支持UTF-8,也就是2003年,而今天使用的UTF-8标准(RFC3629)是随后才出现的。

旧版的UTF-8标准(RFC2279)多支持每个字符6个字节。2002年3月28日,MySQL开发者在一个MySQL41预览版中使用了RFC2279。

同年9月,他们对MySQL源代码进行了一次调整:“UTF8现在多只支持3个字节的序列”。

是谁提交了这些代码他为什么要这样做这个问题不得而知。在迁移到Git后(MySQL开始使用的是BitKeeper),MySQL代码库中的很多提交者的名字都丢失了。2003年9月的邮件列表中也找不到可以解释这一变更的线索。

不同的语言自然有不同的应用领域,虽然有C++这种通用型、多范式的编程语言,但是总体来说大部分编程语言都有自己所擅长的领域和方向。

C/C++语言

理论上C/C++可以进行任何领域的开发,C/C++的优点是效率高,可以说在几乎所有编程语言里面效率最高了,但是因为C/C++学习成本相对较高,尤其是指针这种知识难度比较大,所以做应用开发难度极大,但是做系统级的开发却非常有优势。

常用在系统底层开发,驱动程序开发,嵌入式开发,基础程序开发,以及大型的客户端游戏开发等等。比如你常用的macOS/windows/Linux系统,emacs/vim,visualstudio集成开发环境,文本编辑器等等都离不开C/C++的开发。

Java为业务企业级应用而生

Java的特点是跨平台,是比较彻底的面向对象编程语言,主要用于企业级应用尤其是服务器端开发,比如银行、电子商务、大数据等等领域用得非常多。说得夸张一点,如果没有Java,这个世界都将是黑暗的,阿里巴巴和各大银行就是Java使用量最多的单位,而且在复杂业务逻辑,以及大并发领域Java目前还是有极大的优势。

但是Java语言因为需要跨平台,中间多出来一个JVM,这就使得Java对于硬件资源消耗特别严重,你常用Java继承开发环境IntelliJIDEA和eclipse,尤其是IntelliJIDEA非常占用硬件资源,就是因为这货本身也是用Java开发的。

为Web而生的PHP/JavaScript

毫无疑问,现在最火的是什么?互联网!

那么互联网领域最重要的两款编程语言就是JavaScript和PHP,PHP现在已经非常强大,尤其是在PHP7版本更新以后,在高并发上有了比较大的进步,直接威胁到Java的江湖地位,可以说做业务开发PHP几乎是不二选择了,开发效率非常高,比起Java明明两三句话能扯清楚的事情非要扯半天,PHP简直太友好了。

JavaScript就不用说了,前端语言,现在这货可以做后端了,而且nodejs的势力越来越强大了,虽然这货坑很多,但是依然是社区最活跃的编程语言。

Python/Ruby

其实我一直觉得ruby的语法很优美,然而松本行弘设计了它却没能把Ruby带向辉煌,社区跟不上自然很难大火。

但是Python不一样,虽然这货因为某些不可描述的愿意,不得不两个版本并行,但是即使是这样,也阻止不了Python越来越火,尤其是人工智能现在越来越火,python就开始火得一塌糊涂了,Python的优势是语法极其简单,可读性非常高,入门门槛极低。作为学术研究语言再好不过了,目前在大数据分析、服务器端开发,以及非常红火的人工智能领域有着重要应用。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13300917.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-10
下一篇 2023-07-10

发表评论

登录后才能评论

评论列表(0条)

保存