阿龙的学习笔记---《后台开发:核心技术与应用实践》读书笔记(一)--- 编程语言 与 编译调试

听说是一本腾讯员工写的书,快到面试时候,拿来读一下看看,内容好像不太精,少了一丢丢所以然,但是包含了一些对面试有用的知识点,记录一下。


一、编程语言

  • c语言 是面向函数。

  • size_of 对函数来讲是得到 函数返回值类型 的size。

  • 字节对齐的规则是按照结构体中长度最长的来对齐,比如说有double类型是8byte,那么20字节的结构体会占用24字节的内存。

  • 宏定义一段语句的时候可以使用do…while(0); 这样的话整个代码块还算是一个语句。

  • extern ”C" 告诉编译器用C的方式来编译这一段。

  • 空类的占用空间为1byte,有虚函数的类为一个指针的大小为8byte。

  • 构造函数顺序:先调用基类的构造函数 -> 再调用成员的构造函数 -> 再调用派生类自己的构造函数。子成员对象的构造按照定义顺序,而不是初始化列表的顺序。析构反过来。

  • 重写=覆盖, 覆盖了基类中的virtual函数,必须返回值与参数列表一致,通过不同的指针调用,则调用不同的函数,体现了多态。而重载是参数个数或类型不一致,并无多态的体现,根据参数选择函数运行。最后 重定义(也叫隐藏) 则是重新定义了这个函数,原来的函数被隐藏。

  • 构造函数不能为虚函数:一是因为构造时必须要知道确切的类型,二是调用虚函数需要使用虚指针,而没有构造前又没有虚指针。而需要被继承的类最好设置虚析构函数

  • string类的简易实现

    • 可以参考https://www.cnblogs.com/zhizhan/p/4876093.html

    • 内层是字符指针的操作,有一些需要注意的点,以及一些字符串操作。

    • 通用构造函数:传入字符串指针,需要判断指针是否空,然后new申请内存存放,如果为空,则需要将 ‘/0’ 放入。

      String::String(const char *str)//通用构造函数
      {
      	if(!str){
      		length = 0;
      		data = new char[1];
      		*data = '\0';
      	}else{
      		length = strlen(str);
      		data = new char[length + 1];
      		strcpy(data, str);
      	}
      }
      
    • 拷贝构造函数:需要进行深拷贝,不只是复制指针,而是复制内容。string不会为空,则只需要使用成员函数size(),然后复制内容即可。

      String::String(const String &str)//拷贝构造函数
      {
      	length = str.size();
      	data = new char[length + 1];
      	strcpy(data, str.c_str());
      }
      
    • 析构函数:delete[] 释放内存,改变长度。

      String::~String()//析构函数
      {
      	delete []data;
      	length = 0;
      }
      
    • 拷贝操作符重载:首先要判断自赋值。然后将新的复制过来,长度不定所以需要重新申请内存。

      String& String::operator=(const String &str) //重载=
      {
      	if (this == &str)	
      		return *this;
      	delete []data;
      	length = str.length;
      	data = new char[length + 1];
      	strcpy(data, str.c_str());
      	return *this;
      }
      
    • 获取长度函数:内联加快速度。

      inline size_t String::size() const//获取长度
      {
      	return length;
      }
      
    • 重载输入运算符:先申请一块足够大的内存用来存放输入字符串,再进行新字符串的生成。这是一个比较简单朴素的实现,网上很多直接is>>str.data的方法是错误的,因为不能确定str.data的大小和即将输入的字符串的大小关系。

      istream& operator>>(istream &is, String &str)//输入
      {
      	char tem[1000];  //简单的申请一块内存
      	is >> tem;
      	str.length = strlen(tem);
      	str.data = new char[str.length + 1];
      	strcpy(str.data, tem);
      	return is;
      }
      
    • 重载输出运算符,只需简单地输出字符串的内容即可。注意为了实现形如cout<<a<<b的连续输出,这里需要返回输出流。上面的输入也是类似。

      ostream& operator<<(ostream &os, String &str)//输出
      {
      	os << str.data;
      	return os;
      }
      
    • 获取C字符串:

      inline const char* String::c_str() const//获取C字符串
      {
      	return data;
      }
      
  • vector的简易实现

    • vector底层是一个c格式的数组,通过维护first(开始位置迭代器),last(存储元素的末尾di),end(分配内存的末尾)来工作。
    • 书中实现的方式是通过theSize表示存储元素的末尾,theCapacity表示分配内存的末尾。
    • 通过一个insert_before来实现push_back、push_front、带参数的构造函数。
      在这里插入图片描述
    • 通过一个成员函数allocator()来分配内存、deallocator()来销毁内存。在容量不够的时候,重新分配内存,然后销毁原来内存。
      在这里插入图片描述
    • 拷贝构造函数文中写的是 *this=other,但这样的话是浅拷贝,数组会被直接copy过来。而stl的vector应该是深拷贝,深拷贝则需要将数组中的元素都拷贝过来,而不是只是将指针指向同一个数组,这样会有问题。POD类型可以直接memncpy(),非POD可以for循环然后new。(POD(Plain Old Data,普通旧数据)是指int,float等兼容C的内置类型,支持memncpy)。
    • vector拷贝构造函数——深拷贝也是一个知识点,参考这个博客:https://blog.csdn.net/double_happiness/article/details/71305435。
    • map是键值类型的数据结构,采用红黑树,时间Ologn;unordered_map是:哈希表+bucket解决hash冲突(bucket为链表<8或者红黑树>=8),较好情况下是O(1)。不需要有序的情况下,用哈希的更好。

二、编译调试

  • 静态链接库动态链接库的特点,可以复习一下。

  • GCC 和 G++:

    • G++会把 .c 和 .cpp 文件都当做C++文件。而GCC会区分。
    • G++在编译阶段会调用gcc,因为gcc不能对C++程序进行链接,所以一般都直接用G++。
  • makefile的编写是个问题,没怎么用过,死记硬背也不好记。

  • strace命令可以让你看到一个程序后台运行的系统调用;还可以显示收到的信号;还可以用来统计系统调用的次数等。调试中,可以看到一些系统调用的返回的错误码的值,这样可以定位到程序出错。

  • GDB调试,不仅可以调试运行程序,还可以调试coredump文件。core dump(段错误)是程序发生某些错误时保存下来的一手资料,包含内存值、CPU寄存器的值、函数调用栈等。一般内存越界、多线程竞争问题,非法指针操作,堆栈溢出等情况会触发。

  • top是linux下的性能分析工具,类似任务管理器,显示资源占用情况。可以展示CPU、内存等的总体使用情况,以及各个进程的使用情况。

  • linux下C程序的内存空间布局
    在这里插入图片描述

  • 堆heap和栈stack的区别:

    • 申请方式不同

      • 栈由系统自动分,声明在函数中一个局部变量 int 系统自动在栈中开辟空间。
      • 堆则需要程序员自己申请,并指明大小。
    • 申请响应不同:

      • 栈是自动增长的,有空间则可以申请,否则报栈溢出。
      • 而堆则是类似段表类型,空闲节点链表,一块一块的内存,分配一块够大的,然后占用一部分,剩下的又被分为一块,放入链表中。
    • 申请速度:

      • 栈较快,而堆较慢。
    • 结构:

      • 栈是一块固定大小的空间,有系统限制,一般较小;
      • 而堆是链表结构,不连续,有内存碎片,容量较大,受虚拟内存限制 。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台开发核心技术应用实践 作者:徐晓鑫 著 出版日期:2016年08月06日 封面宣传语:腾讯云平台技术总监黄世飞、Facebook对外支付项目主程张子兴、微软软件工程师彭可竞、阿里巴巴资深算法工程师周乐、百度大数据高级测试工程师畅晋联袂推荐;围绕后台开发需要掌握的核心技术,从多个方面、多个角度进行了阐述,覆盖了该领域的几乎所有内容;充分抓住本质并结合实践,文字通俗易懂,可操作性强 出版书名:后台开发核心技术应用实践 作者:徐晓鑫 著 封底文字 专家评价 后台开发是一个“历史悠久”的领域,同时也是一个沉淀深厚,高技术价值的领域。本书清晰、严谨、务实的风格显示出晓鑫对该领域知识的深刻理解。 ——张子兴 Facebook对外支付项目主程,美国加州MenloPark 每一位从事后台开发的专业人士都需要一本后台开发指南。对每一位想要认真从事该领域工作的人来说,本书是一本绝对必读的书籍。 ——彭可竞 微软软件工程师,美国华盛顿州Redmond 本书是作者多年后台开发、架构和研究的精华。书中用通俗的文字、详尽的示例代码,结合实际工作中的案例,讲述了后台开发方方面面的知识,内容丰富。对于从事后台开发的人员,这是一本很好的由浅入深的学习书籍。 ——周乐 阿里巴巴资深算法工程师,北京望京 使用C++语言进行后台开发有一定的门槛,本书可以很好地帮助你跨过这个“门槛”。 ——畅晋 百度大数据高级测试工程师,北京上地 前勒口 互联网网民日益剧增,各种应用层出不穷,各项技术更新不断。单是游戏行业,近几年就经历了从端游、页游到手游的巨大变迁,客户端更新迭代之快,始料未及。而后台开发中使用到的技术,却变化不是很大。让服务性能更高、处理能力更强、安全性更好,是后台开发工程师永恒的主题。 后台开发中用到的技术,深而广,需要读的“大部头”很多,光是Richard Stevens的APUE,UNP,TCP/IP详解就够读个半年以上。读者通过阅读本书,可以从实践出发,快速由浅入深地进入后台开发领域。在读完本书,有了实践的经验之后,再去阅读大师们的著作,会更有体会,更懂得如何欣赏。 读书的最高境界莫过于“把书读薄,把书读厚”。本书文字通俗易懂,让你更快地“读薄”,同时又涉及较多的核心知识点,顺着这些知识点,读着读着也发觉“读厚”了。 后勒口 徐晓鑫,腾讯资深软件研发工程师,先后在腾讯游戏之洛克王国、QQ会员、QQ秀等项目工作,精通后台开发各种技术,实战经验丰富。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值