随记笔记

一、TCP的三次握手全过程

First:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认。

Second:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。

Third:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHEND状态,完成三次握手。

完成三次握手后,客户端与服务器开始传送数据。


二、死锁

1、产生死锁的原因:竞争资源和进程推进顺序非法。

2、产生死锁的必要条件:互斥条件、请求与保持条件、不剥夺条件和环路等待条件。

3、预防死锁的方法:通过摒弃死锁产生的必要条件来防止死锁发生。

4、具有代表性的避免死锁的算法:“银行家算法”。


三、读下列程序写出输出结果

#include <iostream.h>

class Base

{

public:

virtual ~Base()

{cout  <<  "~base" << endl;}

};

class Derived : public Base

{

public:

virtual ~Derived()

{cout << "~derived" << endl;}

};

void main()

{

Base *pB = new Derived;

delete pB;

}

【输出】~derived

~base

若析构函数不是虚函数,则只输出:~base


四、进程间通信的方式有:共享内存、管道、socket、消息队列、DDE(动态数据交换)、剪贴板、邮件槽、串行/并行通信、COM/DCOM。

五、进程(线程)同步/异步总结:

1、Critical Sention:速度快、不能用于不同进程、不能进行资源统计。

2、Mutex:速度慢、可用于不同进程、不能进行资源统计。

3、Semaphore:速度慢、可用于不同进程、可进行资源统计。

4、Event:速度慢、可用于不同进程、可进行资源统计。


六、排序算法的稳定性:

稳定排序算法有:基数排序算法、冒泡排序算法、插入排序算法、归并排序算法。

不稳定排序算法有:快速排序算法、希尔排序算法、选择排序算法、堆排序算法。


七、内存拷贝函数

void* memcpy(void* pvTo, const void* pvFrom, size_t size)

{

assert((pvTo != NULL) && (pvFrom != NULL));

byte* pbTo = (byte*)pvTo;//防止改变pvTo的地址

byte* pbFrom = (byte*)pvFrom;

while(size-- > 0)

*pbTo++ = *pbFrom++;

return pvTo;

}


八、实现string类的构造函数、拷贝构造函数、析构函数以及赋值函数

class String  
{  
public:  
        String(const char *str = NULL); // 普通构造函数  
        String(const String &other);        // 拷贝构造函数  
        ~ String(void);                     // 析构函数  
        String & operate =(const String &other);    // 赋值函数  
private:  
        char    *m_data;                // 用于保存字符串  
};  
请编写String的上述4个函数。    
  
// String的普通构造函数               
String::String(const char *str) 
{  
    if(str==NULL)                            
    {  
       m_data = new char[1];   
       *m_data = ‘0’;                        
    }                                            
    else  
    {  
       int length = strlen(str);             
       m_data = new char[length+1];        
       strcpy(m_data, str);                  
    }  
}   
  
// 拷贝构造函数  
String::String(const String &other) 
{     
    int length = strlen(other.m_data);   
    m_data = new char[length+1];        
    strcpy(m_data, other.m_data);           

// String的析构函数  
String::~String(void) 
{  
    delete [] m_data;                        
    // 由于m_data是内部数据类型,也可以写成 delete m_data;  

  
// 赋值函数  
String & String::operate =(const String &other) 
{     
       // (1) 检查自赋值 
       if(this == &other)  
           return *this;  
      
       // (2) 释放原有的内存资源
       delete [] m_data;  
         
       // (3)分配新的内存资源,并复制内容 
      int length = strlen(other.m_data);   
      m_data = new char[length+1];   
      strcpy(m_data, other.m_data);  
         
       // (4)返回本对象的引用
       return *this;  
}  


九、面向对象---类
1、类的三大特性:封装、继承、多态。
2、多态:基类指针或引用可以直接引用其任何派生子类,由动态绑定来实现的。
3、构造函数的调用顺序总是如下:
1)基类构造函数如果有多个基类则构造函数的调用顺序是某类在类派生表中出现的顺序而不是它们在成员初始化表中的顺序;
2) 成员类对象构造函数如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序而不是它们出现在成员初始化表中的顺序;
3 )派生类构造函数
4、 构造函数不能为虚函数。原因是在建立一个对象时,构造函数必须知道其确切类型,否则编译器无法进行存贮空间的分配。

十、指针的优缺点
优点: (1)提高程序的编译效率和执行速度。  
(2)通过指针可使主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯。  
(3)可以实现动态的存储分配。  
(4)便于表示各种数据结构,编写高质量的程序。
缺点:容易内存泄漏和产生野指针

十一、函数返回指针时千万不能返回指向“栈”内存的指针。

十二、二分查找法
int binary_search(int* arr, int key, int n)
{
int low = 0;
int high = n-1;
int mid;
while(low <= high)
{
mid = (high + low)/2;
if(arr[mid] > key)
high = mid - 1;
else if(arr[mid] < key)
low = mid + 1;
else
return mid;
}
return -1;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值