💡 关于
📚 本仓库是é¢å‘ C/C++ æŠ€æœ¯æ–¹å‘æ ¡æ‹›æ±‚èŒè€…ã€åˆå¦è€…的基础知识总结,包括è¯è¨€ã€ç¨‹åºåº“ã€æ•°æ®ç»“æž„ã€ç®—法ã€ç³»ç»Ÿã€ç½‘络ã€é“¾æŽ¥è£…载库ç‰çŸ¥è¯†åŠé¢è¯•ç»éªŒã€æ‹›è˜ã€å†…推ç‰ä¿¡æ¯ã€‚
💡 ä¾§è¾¹ç›®å½•æ”¯æŒæ–¹å¼ï¼šðŸ“š Docsify 文档ã€Github + TOC 导航(TOC预览.png)
📄 ä¿å˜ä¸º PDF æ–¹å¼ï¼šä½¿ç”¨ Chrome æµè§ˆå™¨æ‰“å¼€ 📚 Docsify 文档 页é¢ï¼Œç¼©èµ·å·¦ä¾§ç›®å½•-å³é”® - æ‰“å° - é€‰æ‹©ç›®æ ‡æ‰“å°æœºæ˜¯å¦å˜ä¸ºPDF - ä¿å˜ï¼ˆæ‰“å°é¢„览.png)
🙠仓库内容如有错误或改进欢迎 issue 或 pr,建议或讨论å¯åœ¨ #12 æå‡ºã€‚由于本人水平有é™ï¼Œä»“库ä¸çš„知识点有æ¥è‡ªæœ¬äººåŽŸåˆ›ã€è¯»ä¹¦ç¬”è®°ã€ä¹¦ç±ã€åšæ–‡ç‰ï¼ŒéžåŽŸåˆ›å‡å·²æ ‡æ˜Žå‡ºå¤„ï¼Œå¦‚æœ‰é—æ¼ï¼Œè¯· issue æå‡ºã€‚本仓库éµå¾ª CC BY-NC-SA 4.0(署å - éžå•†ä¸šæ€§ä½¿ç”¨ - ç›¸åŒæ–¹å¼å…±äº«ï¼‰ å议,转载请注明出处,ä¸å¾—用于商业目的。
- âž• C/C++
- âï¸ Effective
- 📦 STL
- ã€½ï¸ æ•°æ®ç»“æž„
- âš¡ï¸ ç®—æ³•
- â“ Problems
- 💻 æ“作系统
- â˜ï¸ 计算机网络
- 🌩 网络编程
- 💾 æ•°æ®åº“
- 📠设计模å¼
- âš™ï¸ é“¾æŽ¥è£…è½½åº“
- 📚 书ç±
- 🔱 C/C++ å‘展方å‘
- 💯 å¤ä¹ 刷题网站
- 📠é¢è¯•题目ç»éªŒ
- 📆 æ‹›è˜æ—¶é—´å²—ä½
- 👠内推
- 👬 贡献者
- 📜 License
- 修饰å˜é‡ï¼Œè¯´æ˜Žè¯¥å˜é‡ä¸å¯ä»¥è¢«æ”¹å˜ï¼›
- 修饰指针,分为指å‘常é‡çš„æŒ‡é’ˆï¼ˆpointer to const)和自身是常é‡çš„æŒ‡é’ˆï¼ˆå¸¸é‡æŒ‡é’ˆï¼Œconst pointer);
- 修饰引用,指å‘常é‡çš„引用(reference to const),用于形å‚类型,å³é¿å…了拷è´ï¼Œåˆé¿å…了函数对值的修改;
- 修饰æˆå‘˜å‡½æ•°ï¼Œè¯´æ˜Žè¯¥æˆå‘˜å‡½æ•°å†…ä¸èƒ½ä¿®æ”¹æˆå‘˜å˜é‡ã€‚
- 指针
- 指å‘常é‡çš„æŒ‡é’ˆï¼ˆpointer to const)
- 自身是常é‡çš„æŒ‡é’ˆï¼ˆå¸¸é‡æŒ‡é’ˆï¼Œconst pointer)
- 引用
- 指å‘常é‡çš„引用(reference to const)
- 没有 const referenceï¼Œå› ä¸ºå¼•ç”¨åªæ˜¯å¯¹è±¡çš„别åï¼Œå¼•ç”¨ä¸æ˜¯å¯¹è±¡ï¼Œä¸èƒ½ç”¨ const 修饰
(为了方便记忆å¯ä»¥æƒ³æˆï¼‰è¢« const 修饰(在 const åŽé¢ï¼‰çš„值ä¸å¯æ”¹å˜ï¼Œå¦‚下文使用例åä¸çš„
p2
ã€p3
const 使用
// ç±»
class A
{
private:
const int a; // 常对象æˆå‘˜ï¼Œå¯ä»¥ä½¿ç”¨åˆå§‹åŒ–列表或者类内åˆå§‹åŒ–
public:
// æž„é€ å‡½æ•°
A() : a(0) { };
A(int x) : a(x) { }; // åˆå§‹åŒ–列表
// constå¯ç”¨äºŽå¯¹é‡è½½å‡½æ•°çš„区分
int getValue(); // 普通æˆå‘˜å‡½æ•°
int getValue() const; // 常æˆå‘˜å‡½æ•°ï¼Œä¸å¾—修改类ä¸çš„ä»»ä½•æ•°æ®æˆå‘˜çš„值
};
void function()
{
// 对象
A b; // 普通对象,å¯ä»¥è°ƒç”¨å…¨éƒ¨æˆå‘˜å‡½æ•°
const A a; // 常对象,åªèƒ½è°ƒç”¨å¸¸æˆå‘˜å‡½æ•°
const A *p = &a; // 指针å˜é‡ï¼ŒæŒ‡å‘常对象
const A &q = a; // 指å‘常对象的引用
// 指针
char greeting[] = "Hello";
char* p1 = greeting; // 指针å˜é‡ï¼ŒæŒ‡å‘å—符数组å˜é‡
const char* p2 = greeting; // 指针å˜é‡ï¼ŒæŒ‡å‘å—符数组常é‡ï¼ˆconst åŽé¢æ˜¯ char,说明指å‘çš„å—符(char)ä¸å¯æ”¹å˜ï¼‰
char* const p3 = greeting; // 自身是常é‡çš„æŒ‡é’ˆï¼ŒæŒ‡å‘å—符数组å˜é‡ï¼ˆconst åŽé¢æ˜¯ p3,说明 p3 指针自身ä¸å¯æ”¹å˜ï¼‰
const char* const p4 = greeting; // 自身是常é‡çš„æŒ‡é’ˆï¼ŒæŒ‡å‘å—符数组常é‡
}
// 函数
void function1(const int Var); // ä¼ é€’è¿‡æ¥çš„傿•°åœ¨å‡½æ•°å†…ä¸å¯å˜
void function2(const char* Var); // 傿•°æŒ‡é’ˆæ‰€æŒ‡å†…容为常é‡
void function3(char* const Var); // 傿•°æŒ‡é’ˆä¸ºå¸¸é‡
void function4(const int& Var); // å¼•ç”¨å‚æ•°åœ¨å‡½æ•°å†…为常é‡
// 函数返回值
const int function5(); // 返回一个常数
const int* function6(); // 返回一个指å‘常é‡çš„æŒ‡é’ˆå˜é‡ï¼Œä½¿ç”¨ï¼šconst int *p = function6();
int* const function7(); // 返回一个指å‘å˜é‡çš„常指针,使用:int* const p = function7();
å®å®šä¹‰ #define | const å¸¸é‡ |
---|---|
å®å®šä¹‰ï¼Œç›¸å½“于å—ç¬¦æ›¿æ¢ | 常é‡å£°æ˜Ž |
预处ç†å™¨å¤„ç† | ç¼–è¯‘å™¨å¤„ç† |
æ— ç±»åž‹å®‰å…¨æ£€æŸ¥ | 有类型安全检查 |
ä¸åˆ†é…å†…å˜ | è¦åˆ†é…å†…å˜ |
å˜å‚¨åœ¨ä»£ç 段 | å˜å‚¨åœ¨æ•°æ®æ®µ 528C td> |
å¯é€šè¿‡ #undef å–æ¶ˆ |
ä¸å¯å–消 |
- 修饰普通å˜é‡ï¼Œä¿®æ”¹å˜é‡çš„å˜å‚¨åŒºåŸŸå’Œç”Ÿå‘½å‘¨æœŸï¼Œä½¿å˜é‡å˜å‚¨åœ¨é™æ€åŒºï¼Œåœ¨ main 函数è¿è¡Œå‰å°±åˆ†é…了空间,如果有åˆå§‹å€¼å°±ç”¨åˆå§‹å€¼åˆå§‹åŒ–它,如果没有åˆå§‹å€¼ç³»ç»Ÿç”¨é»˜è®¤å€¼åˆå§‹åŒ–它。
- 修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内æ‰èƒ½ä½¿ç”¨ã€‚在多人开å‘项目时,为了防æ¢ä¸Žä»–人命å空间里的函数é‡å,å¯ä»¥å°†å‡½æ•°å®šä½ä¸º static。
- 修饰æˆå‘˜å˜é‡ï¼Œä¿®é¥°æˆå‘˜å˜é‡ä½¿æ‰€æœ‰çš„对象åªä¿å˜ä¸€ä¸ªè¯¥å˜é‡ï¼Œè€Œä¸”ä¸éœ€è¦ç”Ÿæˆå¯¹è±¡å°±å¯ä»¥è®¿é—®è¯¥æˆå‘˜ã€‚
- 修饰æˆå‘˜å‡½æ•°ï¼Œä¿®é¥°æˆå‘˜å‡½æ•°ä½¿å¾—ä¸éœ€è¦ç”Ÿæˆå¯¹è±¡å°±å¯ä»¥è®¿é—®è¯¥å‡½æ•°ï¼Œä½†æ˜¯åœ¨ static 函数内ä¸èƒ½è®¿é—®éžé™æ€æˆå‘˜ã€‚
this
指针是一个éšå«äºŽæ¯ä¸€ä¸ªéžé™æ€æˆå‘˜å‡½æ•°ä¸çš„特殊指针。它指å‘调用该æˆå‘˜å‡½æ•°çš„那个对象。- 当对一个对象调用æˆå‘˜å‡½æ•°æ—¶ï¼Œç¼–译程åºå…ˆå°†å¯¹è±¡çš„地å€èµ‹ç»™
this
指针,然åŽè°ƒç”¨æˆå‘˜å‡½æ•°ï¼Œæ¯æ¬¡æˆå‘˜å‡½æ•°å˜å–æ•°æ®æˆå‘˜æ—¶ï¼Œéƒ½éšå¼ä½¿ç”¨this
指针。 - 当一个æˆå‘˜å‡½æ•°è¢«è°ƒç”¨æ—¶ï¼Œè‡ªåЍå‘å®ƒä¼ é€’ä¸€ä¸ªéšå«çš„傿•°ï¼Œè¯¥å‚数是一个指å‘这个æˆå‘˜å‡½æ•°æ‰€åœ¨çš„对象的指针。
this
指针被éšå«åœ°å£°æ˜Žä¸º:ClassName *const this
,这æ„味ç€ä¸èƒ½ç»™this
指针赋值;在ClassName
类的const
æˆå‘˜å‡½æ•°ä¸ï¼Œthis
指针的类型为:const ClassName* const
,这说明ä¸èƒ½å¯¹this
指针所指å‘的这ç§å¯¹è±¡æ˜¯ä¸å¯ä¿®æ”¹çš„(å³ä¸èƒ½å¯¹è¿™ç§å¯¹è±¡çš„æ•°æ®æˆå‘˜è¿›è¡Œèµ‹å€¼æ“作);this
并䏿˜¯ä¸€ä¸ªå¸¸è§„å˜é‡ï¼Œè€Œæ˜¯ä¸ªå³å€¼ï¼Œæ‰€ä»¥ä¸èƒ½å–å¾—this
的地å€ï¼ˆä¸èƒ½&this
)。- 在以下场景ä¸ï¼Œç»å¸¸éœ€è¦æ˜¾å¼å¼•用
this
指针:- 为实现对象的链å¼å¼•用;
- 为é¿å…对åŒä¸€å¯¹è±¡è¿›è¡Œèµ‹å€¼æ“作;
- 在实现一些数æ®ç»“构时,如
list
。
- 相当于把内è”函数里é¢çš„内容写在调用内è”函数处;
- 相当于ä¸ç”¨æ‰§è¡Œè¿›å…¥å‡½æ•°çš„æ¥éª¤ï¼Œç›´æŽ¥æ‰§è¡Œå‡½æ•°ä½“ï¼›
- 相当于å®ï¼Œå´æ¯”å®å¤šäº†ç±»åž‹æ£€æŸ¥ï¼ŒçœŸæ£å…·æœ‰å‡½æ•°ç‰¹æ€§ï¼›
- 编译器一般ä¸å†…è”包å«å¾ªçޝã€é€’å½’ã€switch ç‰å¤æ‚æ“作的内è”函数;
- 在类声明ä¸å®šä¹‰çš„函数,除了虚函数的其他函数都会自动éšå¼åœ°å½“æˆå†…è”函数。
inline 使用
// 声明1ï¼ˆåŠ inline,建议使用)
inline int functionName(int first, int second,...);
// 声明2(ä¸åŠ inline)
int functionName(int first, int second,...);
// 定义
inline int functionName(int first, int second,...) {/****/};
// 类内定义,éšå¼å†…è”
class A {
int doA() { return 0; } // éšå¼å†…è”
}
// ç±»å¤–å®šä¹‰ï¼Œéœ€è¦æ˜¾å¼å†…è”
class A {
int doA();
}
inline int A::doA() { return 0; } // éœ€è¦æ˜¾å¼å†…è”
- å°† inline 函数体å¤åˆ¶åˆ° inline 函数调用点处;
- 为所用 inline 函数ä¸çš„局部å˜é‡åˆ†é…内å˜ç©ºé—´ï¼›
- å°† inline å‡½æ•°çš„çš„è¾“å…¥å‚æ•°å’Œè¿”å›žå€¼æ˜ å°„åˆ°è°ƒç”¨æ–¹æ³•çš„å±€éƒ¨å˜é‡ç©ºé—´ä¸ï¼›
- 如果 inline 函数有多个返回点,将其转å˜ä¸º inline 函数代ç å—æœ«å°¾çš„分支(使用 GOTO)。
优点
- 内è”函数åŒå®å‡½æ•°ä¸€æ ·å°†åœ¨è¢«è°ƒç”¨å¤„进行代ç 展开,çœåŽ»äº†å‚æ•°åŽ‹æ ˆã€æ ˆå¸§å¼€è¾Ÿä¸Žå›žæ”¶ï¼Œç»“果返回ç‰ï¼Œä»Žè€Œæé«˜ç¨‹åºè¿è¡Œé€Ÿåº¦ã€‚
- 内è”函数相比å®å‡½æ•°æ¥è¯´ï¼Œåœ¨ä»£ç 展开时,会åšå®‰å…¨æ£€æŸ¥æˆ–自动类型转æ¢ï¼ˆåŒæ™®é€šå‡½æ•°ï¼‰ï¼Œè€Œå®å®šä¹‰åˆ™ä¸ä¼šã€‚
- 在类ä¸å£°æ˜ŽåŒæ—¶å®šä¹‰çš„æˆå‘˜å‡½æ•°ï¼Œè‡ªåŠ¨è½¬åŒ–ä¸ºå†…è”å‡½æ•°ï¼Œå› æ¤å†…è”函数å¯ä»¥è®¿é—®ç±»çš„æˆå‘˜å˜é‡ï¼Œå®å®šä¹‰åˆ™ä¸èƒ½ã€‚
- 内è”函数在è¿è¡Œæ—¶å¯è°ƒè¯•,而å®å®šä¹‰ä¸å¯ä»¥ã€‚
缺点
- 代ç è†¨èƒ€ã€‚å†…è”æ˜¯ä»¥ä»£ç 膨胀(å¤åˆ¶ï¼‰ä¸ºä»£ä»·ï¼Œæ¶ˆé™¤å‡½æ•°è°ƒç”¨å¸¦æ¥çš„开销。如果执行函数体内代ç 的时间,相比于函数调用的开销较大,那么效率的收获会很少。å¦ä¸€æ–¹é¢ï¼Œæ¯ä¸€å¤„内è”函数的调用都è¦å¤åˆ¶ä»£ç ,将使程åºçš„æ€»ä»£ç é‡å¢žå¤§ï¼Œæ¶ˆè€—更多的内å˜ç©ºé—´ã€‚
- inline å‡½æ•°æ— æ³•éšç€å‡½æ•°åº“å‡çº§è€Œå‡çº§ã€‚inline函数的改å˜éœ€è¦é‡æ–°ç¼–译,ä¸åƒ non-inline å¯ä»¥ç›´æŽ¥é“¾æŽ¥ã€‚
- 是å¦å†…è”,程åºå‘˜ä¸å¯æŽ§ã€‚内è”å‡½æ•°åªæ˜¯å¯¹ç¼–译器的建议,是å¦å¯¹å‡½æ•°å†…è”,决定æƒåœ¨äºŽç¼–译器。
Are "inline virtual" member functions ever actually "inlined"?
- 虚函数å¯ä»¥æ˜¯å†…è”å‡½æ•°ï¼Œå†…è”æ˜¯å¯ä»¥ä¿®é¥°è™šå‡½æ•°çš„ï¼Œä½†æ˜¯å½“è™šå‡½æ•°è¡¨çŽ°å¤šæ€æ€§çš„æ—¶å€™ä¸èƒ½å†…è”。
- å†…è”æ˜¯åœ¨ç¼–译期建议编译器内è”ï¼Œè€Œè™šå‡½æ•°çš„å¤šæ€æ€§åœ¨è¿è¡ŒæœŸï¼Œç¼–è¯‘å™¨æ— æ³•çŸ¥é“è¿è¡ŒæœŸè°ƒç”¨å“ªä¸ªä»£ç ï¼Œå› æ¤è™šå‡½æ•°è¡¨çŽ°ä¸ºå¤šæ€æ€§æ—¶ï¼ˆè¿è¡ŒæœŸï¼‰ä¸å¯ä»¥å†…è”。
inline virtual
唯一å¯ä»¥å†…è”çš„æ—¶å€™æ˜¯ï¼šç¼–è¯‘å™¨çŸ¥é“æ‰€è°ƒç”¨çš„对象是哪个类(如Base::who()
ï¼‰ï¼Œè¿™åªæœ‰åœ¨ç¼–è¯‘å™¨å…·æœ‰å®žé™…å¯¹è±¡è€Œä¸æ˜¯å¯¹è±¡çš„æŒ‡é’ˆæˆ–引用时æ‰ä¼šå‘生。
虚函数内è”使用
#include <iostream>
using namespace std;
class Base
{
public:
inline virtual void who()
{
cout << "I am Base\n";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
inline void who() // ä¸å†™inlineæ—¶éšå¼å†…è”
{
cout << "I am Derived\n";
}
};
int main()
{
// æ¤å¤„的虚函数 who(),是通过类(Base)的具体对象(b)æ¥è°ƒç”¨çš„,编译期间就能确定了,所以它å¯ä»¥æ˜¯å†…è”的,但最终是å¦å†…è”å–决于编译器。
Base b;
b.who();
// æ¤å¤„çš„è™šå‡½æ•°æ˜¯é€šè¿‡æŒ‡é’ˆè°ƒç”¨çš„ï¼Œå‘ˆçŽ°å¤šæ€æ€§ï¼Œéœ€è¦åœ¨è¿è¡Œæ—¶æœŸé—´æ‰èƒ½ç¡®å®šï¼Œæ‰€ä»¥ä¸èƒ½ä¸ºå†…è”。
Base *ptr = new Derived();
ptr->who();
// å› ä¸ºBaseæœ‰è™šæžæž„函数(virtual ~Base() {}),所以 delete 时,会先调用派生类(Derivedï¼‰æžæž„函数,å†è°ƒç”¨åŸºç±»ï¼ˆBaseï¼‰æžæž„函数,防æ¢å†…å˜æ³„æ¼ã€‚
delete ptr;
ptr = nullptr;
system("pause");
return 0;
}
volatile int i = 10;
- volatile 关键嗿˜¯ä¸€ç§ç±»åž‹ä¿®é¥°ç¬¦ï¼Œç”¨å®ƒå£°æ˜Žçš„类型å˜é‡è¡¨ç¤ºå¯ä»¥è¢«æŸäº›ç¼–è¯‘å™¨æœªçŸ¥çš„å› ç´ ï¼ˆæ“作系统ã€ç¡¬ä»¶ã€å…¶å®ƒçº¿ç¨‹ç‰ï¼‰æ›´æ”¹ã€‚所以使用 volatile 告诉编译器ä¸åº”å¯¹è¿™æ ·çš„å¯¹è±¡è¿›è¡Œä¼˜åŒ–ã€‚
- volatile 关键å—声明的å˜é‡ï¼Œæ¯æ¬¡è®¿é—®æ—¶éƒ½å¿…须从内å˜ä¸å–出值(没有被 volatile 修饰的å˜é‡ï¼Œå¯èƒ½ç”±äºŽç¼–译器的优化,从 CPU 寄å˜å™¨ä¸å–值)
- const å¯ä»¥æ˜¯ volatile (如åªè¯»çš„çŠ B93C ¶æ€å¯„å˜å™¨ï¼‰
- 指针å¯ä»¥æ˜¯ volatile
æ–言,是å®ï¼Œè€Œéžå‡½æ•°ã€‚assert å®çš„原型定义在 <assert.h>
(C)ã€<cassert>
(C++)ä¸ï¼Œå…¶ä½œç”¨æ˜¯å¦‚果它的æ¡ä»¶è¿”回错误,则终æ¢ç¨‹åºæ‰§è¡Œã€‚å¯ä»¥é€šè¿‡å®šä¹‰ NDEBUG
æ¥å…³é— assert,但是需è¦åœ¨æºä»£ç 的开头,include <assert.h>
之å‰ã€‚
assert() 使用
#define NDEBUG // åŠ ä¸Šè¿™è¡Œï¼Œåˆ™ assert ä¸å¯ç”¨
#include <assert.h>
assert( p != NULL ); // assert ä¸å¯ç”¨
- sizeof 对数组,得到整个数组所å 空间大å°ã€‚
- sizeof 对指针,得到指针本身所å 空间大å°ã€‚
设定结构体ã€è”åˆä»¥åŠç±»æˆå‘˜å˜é‡ä»¥ n å—节方å¼å¯¹é½
#pragma pack(n) 使用
#pragma pack(push) // ä¿å˜å¯¹é½çжæ€
#pragma pack(4) // 设定为 4 å—节对é½
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop) // æ¢å¤å¯¹é½çжæ€
Bit mode: 2; // mode å 2 ä½
ç±»å¯ä»¥å°†å…¶ï¼ˆéžé™æ€ï¼‰æ•°æ®æˆå‘˜å®šä¹‰ä¸ºä½åŸŸï¼ˆbit-field),在一个ä½åŸŸä¸å«æœ‰ä¸€å®šæ•°é‡çš„二进制ä½ã€‚当一个程åºéœ€è¦å‘å…¶ä»–ç¨‹åºæˆ–ç¡¬ä»¶è®¾å¤‡ä¼ é€’äºŒè¿›åˆ¶æ•°æ®æ—¶ï¼Œé€šå¸¸ä¼šç”¨åˆ°ä½åŸŸã€‚
- ä½åŸŸåœ¨å†…å˜ä¸çš„布局是与机器有关的
- ä½åŸŸçš„类型必须是整型或枚举类型,带符å·ç±»åž‹ä¸çš„ä½åŸŸçš„è¡Œä¸ºå°†å› å…·ä½“å®žçŽ°è€Œå®š
- å–地å€è¿ç®—符(&)ä¸èƒ½ä½œç”¨äºŽä½åŸŸï¼Œä»»ä½•æŒ‡é’ˆéƒ½æ— æ³•æŒ‡å‘类的ä½åŸŸ
- 被 extern é™å®šçš„函数或å˜é‡æ˜¯ extern 类型的
- 被
extern "C"
修饰的å˜é‡å’Œå‡½æ•°æ˜¯æŒ‰ç…§ C è¯è¨€æ–¹å¼ç¼–译和链接的
extern "C"
的作用是让 C++ 编译器将 extern "C"
声明的代ç 当作 C è¯è¨€ä»£ç 处ç†ï¼Œå¯ä»¥é¿å… C++ å› ç¬¦å·ä¿®é¥°å¯¼è‡´ä»£ç ä¸èƒ½å’ŒCè¯è¨€åº“ä¸çš„符å·è¿›è¡Œé“¾æŽ¥çš„问题。
extern "C" 使用
#ifdef __cplusplus
extern "C" {
#endif
void *memset(void *, int, size_t);
#ifdef __cplusplus
}
#endif
// c
typedef struct Student {
int age;
} S;
ç‰ä»·äºŽ
// c
struct Student {
int age;
};
typedef struct Student S;
æ¤æ—¶ S
ç‰ä»·äºŽ struct Student
ï¼Œä½†ä¸¤ä¸ªæ ‡è¯†ç¬¦å称空间ä¸ç›¸åŒã€‚
å¦å¤–还å¯ä»¥å®šä¹‰ä¸Ž struct Student
ä¸å†²çªçš„ void Student() {}
。
由于编译器定ä½ç¬¦å·çš„规则(æœç´¢è§„则)改å˜ï¼Œå¯¼è‡´ä¸åŒäºŽCè¯è¨€ã€‚
一ã€å¦‚æžœåœ¨ç±»æ ‡è¯†ç¬¦ç©ºé—´å®šä¹‰äº† struct Student {...};
,使用 Student me;
时,编译器将æœç´¢å…¨å±€æ ‡è¯†ç¬¦è¡¨ï¼ŒStudent
æœªæ‰¾åˆ°ï¼Œåˆ™åœ¨ç±»æ ‡è¯†ç¬¦å†…æœç´¢ã€‚
å³è¡¨çŽ°ä¸ºå¯ä»¥ä½¿ç”¨ Student
也å¯ä»¥ä½¿ç”¨ struct Student
,如下:
// cpp
struct Student {
int age;
};
void f( Student me ); // æ£ç¡®ï¼Œ"struct" 关键å—å¯çœç•¥
二ã€è‹¥å®šä¹‰äº†ä¸Ž Student
åŒå函数之åŽï¼Œåˆ™ Student
åªä»£è¡¨å‡½æ•°ï¼Œä¸ä»£è¡¨ç»“构体,如下:
typedef struct Student {
int age;
} S;
void Student() {} // æ£ç¡®ï¼Œå®šä¹‰åŽ "Student" åªä»£è¡¨æ¤å‡½æ•°
//void S() {} // é”™è¯¯ï¼Œç¬¦å· "S" å·²ç»è¢«å®šä¹‰ä¸ºä¸€ä¸ª "struct Student" 的别å
int main() {
Student();
struct Student me; // 或者 "S me";
return 0;
}
总的æ¥è¯´ï¼Œstruct 更适åˆçœ‹æˆæ˜¯ä¸€ä¸ªæ•°æ®ç»“构的实现体,class 更适åˆçœ‹æˆæ˜¯ä¸€ä¸ªå¯¹è±¡çš„实现体。
- 最本质的一个区别就是默认的访问控制
- 默认的继承访问æƒé™ã€‚struct 是 public 的,class 是 private 的。
- struct 作为数æ®ç»“构的实现体,它默认的数æ®è®¿é—®æŽ§åˆ¶æ˜¯ public 的,而 class 作为对象的实现体,它默认的æˆå‘˜å˜é‡è®¿é—®æŽ§åˆ¶æ˜¯ private 的。
è”åˆï¼ˆunion)是一ç§èŠ‚çœç©ºé—´çš„特殊的类,一个 union å¯ä»¥æœ‰å¤šä¸ªæ•°æ®æˆå‘˜ï¼Œä½†æ˜¯åœ¨ä»»æ„æ—¶åˆ»åªæœ‰ä¸€ä¸ªæ•°æ®æˆå‘˜å¯ä»¥æœ‰å€¼ã€‚当æŸä¸ªæˆå‘˜è¢«èµ‹å€¼åŽå…¶ä»–æˆå‘˜å˜ä¸ºæœªå®šä¹‰çжæ€ã€‚è”åˆæœ‰å¦‚下特点:
- 默认访问控制符为 public
- å¯ä»¥å«æœ‰æž„é€ å‡½æ•°ã€æžæž„函数
- ä¸èƒ½å«æœ‰å¼•用类型的æˆå‘˜
- ä¸èƒ½ç»§æ‰¿è‡ªå…¶ä»–类,ä¸èƒ½ä½œä¸ºåŸºç±»
- ä¸èƒ½å«æœ‰è™šå‡½æ•°
- 匿å union 在定义所在作用域å¯ç›´æŽ¥è®¿é—® union æˆå‘˜
- 匿å union ä¸èƒ½åŒ…å« protected æˆå‘˜æˆ– private æˆå‘˜
- 全局匿åè”åˆå¿…é¡»æ˜¯é™æ€ï¼ˆstatic)的
union 使用
#include<iostream>
union UnionTest {
UnionTest() : i(10) {};
int i;
double d;
};
static union {
int i;
double d;
};
int main() {
UnionTest u;
union {
int i;
double d;
};
std::cout << u.i << std::endl; // 输出 UnionTest è”åˆçš„ 10
::i = 20;
std::cout << ::i << std::endl; // è¾“å‡ºå…¨å±€é™æ€åŒ¿åè”åˆçš„ 20
i = 30;
std::cout << i << std::endl; // 输出局部匿åè”åˆçš„ 30
return 0;
}
C 实现 C++ çš„é¢å‘对象特性(å°è£…ã€ç»§æ‰¿ã€å¤šæ€ï¼‰
- å°è£…:使用函数指针把属性与方法å°è£…到结构体ä¸
- 继承:结构体嵌套
- 多æ€ï¼šçˆ¶ç±»ä¸Žå类方法的函数指针ä¸åŒ
- explicit ä¿®é¥°æž„é€ å‡½æ•°æ—¶ï¼Œå¯ä»¥é˜²æ¢éšå¼è½¬æ¢å’Œå¤åˆ¶åˆå§‹åŒ–
- explicit 修饰转æ¢å‡½æ•°æ—¶ï¼Œå¯ä»¥é˜²æ¢éšå¼è½¬æ¢ï¼Œä½† 按è¯å¢ƒè½¬æ¢ 除外
explicit 使用
struct A
{
A(int) { }
operator bool() const { return true; }
};
struct B
{
explicit B(int) {}
explicit operator bool() const { return true; }
};
void doA(A a) {}
void doB(B b) {}
int main()
{
A a1(1); // OK:直接åˆå§‹åŒ–
A a2 = 1; // OK:å¤åˆ¶åˆå§‹åŒ–
A a3{ 1 }; // OK:直接列表åˆå§‹åŒ–
A a4 = { 1 }; // OK:å¤åˆ¶åˆ—表åˆå§‹åŒ–
A a5 = (A)1; // OK:å…许 static_cast 的显å¼è½¬æ¢
doA(1); // OK:å…许从 int 到 A çš„éšå¼è½¬æ¢
if (a1); // OK:使用转æ¢å‡½æ•° A::operator bool() 的从 A 到 bool çš„éšå¼è½¬æ¢
bool a6(a1); // OK:使用转æ¢å‡½æ•° A::operator bool() 的从 A 到 bool çš„éšå¼è½¬æ¢
bool a7 = a1; // OK:使用转æ¢å‡½æ•° A::operator bool() 的从 A 到 bool çš„éšå¼è½¬æ¢
bool a8 = static_cast<bool>(a1); // OK :static_cast 进行直接åˆå§‹åŒ–
B b1(1); // OK:直接åˆå§‹åŒ–
B b2 = 1; // 错误:被 explicit ä¿®é¥°æž„é€ å‡½æ•°çš„å¯¹è±¡ä¸å¯ä»¥å¤åˆ¶åˆå§‹åŒ–
B b3{ 1 }; // OK:直接列表åˆå§‹åŒ–
B b4 = { 1 }; // 错误:被 explicit ä¿®é¥°æž„é€ å‡½æ•°çš„å¯¹è±¡ä¸å¯ä»¥å¤åˆ¶åˆ—表åˆå§‹åŒ–
B b5 = (B)1; // OK:å…许 static_cast 的显å¼è½¬æ¢
doB(1); // 错误:被 explicit ä¿®é¥°æž„é€ å‡½æ•°çš„å¯¹è±¡ä¸å¯ä»¥ä»Ž int 到 B çš„éšå¼è½¬æ¢
if (b1); // OK:被 explicit 修饰转æ¢å‡½æ•° B::operator bool() 的对象å¯ä»¥ä»Ž B 到 bool 的按è¯å¢ƒè½¬æ¢
bool b6(b1); // OK:被 explicit 修饰转æ¢å‡½æ•° B::operator bool() 的对象å¯ä»¥ä»Ž B 到 bool 的按è¯å¢ƒè½¬æ¢
bool b7 = b1; // 错误:被 explicit 修饰转æ¢å‡½æ•° B::operator bool() 的对象ä¸å¯ä»¥éšå¼è½¬æ¢
bool b8 = static_cast<bool>(b1); // OK:static_cast 进行直接åˆå§‹åŒ–
return 0;
}
- èƒ½è®¿é—®ç§æœ‰æˆå‘˜
- ç ´åå°è£…性
- å‹å…ƒå…³ç³»ä¸å¯ä¼ 递
- å‹å…ƒå…³ç³»çš„å•呿€§
- å‹å…ƒå£°æ˜Žçš„å½¢å¼åŠæ•°é‡ä¸å—é™åˆ¶
ä¸€æ¡ using 声明
è¯å¥ä¸€æ¬¡åªå¼•入命å空间的一个æˆå‘˜ã€‚它使得我们å¯ä»¥æ¸…楚知é“程åºä¸æ‰€å¼•用的到底是哪个åå—。如:
using namespace_name::name;
在 C++11 ä¸ï¼Œæ´¾ç”Ÿç±»èƒ½å¤Ÿé‡ç”¨å…¶ç›´æŽ¥åŸºç±»å®šä¹‰çš„æž„é€ å‡½æ•°ã€‚
class Derived : Base {
public:
using Base::Base;
/* ... */
};
如上 using 声明,对于基类的æ¯ä¸ªæž„é€ å‡½æ•°ï¼Œç¼–è¯‘å™¨éƒ½ç”Ÿæˆä¸€ä¸ªä¸Žä¹‹å¯¹åº”(形å‚列表完全相åŒï¼‰çš„æ´¾ç”Ÿç±»æž„é€ å‡½æ•°ã€‚ç”Ÿæˆå¦‚ä¸‹ç±»åž‹æž„é€ å‡½æ•°ï¼š
Derived(parms) : Base(args) { }
using 指示
使得æŸä¸ªç‰¹å®šå‘½åç©ºé—´ä¸æ‰€æœ‰åå—都å¯è§ï¼Œè¿™æ ·æˆ‘ä»¬å°±æ— éœ€å†ä¸ºå®ƒä»¬æ·»åР任何å‰ç¼€é™å®šç¬¦äº†ã€‚如:
using namespace_name name;
一般说æ¥ï¼Œä½¿ç”¨ using 命令比使用 using 编译命令更安全,这是由于它åªå¯¼å…¥äº†æŒ‡å®šçš„å称。如果该å称与局部åç§°å‘生冲çªï¼Œç¼–译器将å‘出指示。using编译命令导入所有的å称,包括å¯èƒ½å¹¶ä¸éœ€è¦çš„å称。如果与局部åç§°å‘生冲çªï¼Œåˆ™å±€éƒ¨å称将覆盖å称空间版本,而编译器并ä¸ä¼šå‘出è¦å‘Šã€‚å¦å¤–,å称空间的开放性æ„味ç€å称空间的åç§°å¯èƒ½åˆ†æ•£åœ¨å¤šä¸ªåœ°æ–¹ï¼Œè¿™ä½¿å¾—éš¾ä»¥å‡†ç¡®çŸ¥é“æ·»åŠ äº†å“ªäº›å称。
using 使用
å°½é‡å°‘使用 using 指示
using namespace std;
应该多使用 using 声明
int x;
std::cin >> x ;
std::cout << x << std::endl;
或者
using std::cin;
using std::cout;
using std::endl;
int x;
cin >> x;
cout << x << endl;
- 全局作用域符(
::name
):用于类型å称(类ã€ç±»æˆå‘˜ã€æˆå‘˜å‡½æ•°ã€å˜é‡ç‰ï¼‰å‰ï¼Œè¡¨ç¤ºä½œç”¨åŸŸä¸ºå…¨å±€å‘½å空间 - 类作用域符(
class::name
):用于表示指定类型的作用域范围是具体æŸä¸ªç±»çš„ - 命å空间作用域符(
namespace::name
):用于表示指定类型的作用域范围是具体æŸä¸ªå‘½å空间的
:: 使用
int count = 11; // 全局(::)的 count
class A {
public:
static int count; // 类 A 的 count(A::count)
};
int A::count = 21;
void fun()
{
int count = 31; // åˆå§‹åŒ–局部的 count 为 31
count = 32; // 设置局部的 count 的值为 32
}
int main() {
::count = 12; // 测试 1:设置全局的 count 的值为 12
A::count = 22; // 测试 2:设置类 A 的 count 为 22
fun(); // 测试 3
return 0;
}
enum class open_modes { input, output, append };
enum color { red, yellow, green };
enum { floatPrec = 6, doublePrec = 10 };
decltype 关键å—用于检查实体的声明类型或表达å¼çš„类型åŠå€¼åˆ†ç±»ã€‚è¯æ³•:
decltype ( expression )
decltype 使用
// 尾置返回å…è®¸æˆ‘ä»¬åœ¨å‚æ•°åˆ—表之åŽå£°æ˜Žè¿”回类型
template <typename It>
auto fcn(It beg, It end) -> decltype(*beg)
{
// 处ç†åºåˆ—
return *beg; // 返回åºåˆ—ä¸ä¸€ä¸ªå…ƒç´ 的引用
}
// 为了使用模æ¿å‚æ•°æˆå‘˜ï¼Œå¿…须用 typename
template <typename It>
auto fcn2(It beg, It end) -> typename remove_reference<decltype(*beg)>::type
{
// 处ç†åºåˆ—
return *beg; // 返回åºåˆ—ä¸ä¸€ä¸ªå…ƒç´ 的拷è´
}
常规引用,一般表示对象的身份。
å³å€¼å¼•用就是必须绑定到å³å€¼ï¼ˆä¸€ä¸ªä¸´æ—¶å¯¹è±¡ã€å°†è¦é”€æ¯çš„对象)的引用,一般表示对象的值。
å³å€¼å¼•用å¯å®žçŽ°è½¬ç§»è¯ä¹‰ï¼ˆMove Sementicsï¼‰å’Œç²¾ç¡®ä¼ é€’ï¼ˆPerfect Forwarding),它的主è¦ç›®çš„æœ‰ä¸¤ä¸ªæ–¹é¢ï¼š
- 消除两个对象交互时ä¸å¿…è¦çš„对象拷è´ï¼ŒèŠ‚çœè¿ç®—å˜å‚¨èµ„æºï¼Œæé«˜æ•ˆçŽ‡ã€‚
- èƒ½å¤Ÿæ›´ç®€æ´æ˜Žç¡®åœ°å®šä¹‰æ³›åž‹å‡½æ•°ã€‚
X& &
ã€X& &&
ã€X&& &
å¯æŠ˜å æˆX&
X&& &&
å¯æŠ˜å æˆX&&
- å®å®šä¹‰å¯ä»¥å®žçŽ°ç±»ä¼¼äºŽå‡½æ•°çš„åŠŸèƒ½ï¼Œä½†æ˜¯å®ƒç»ˆå½’ä¸æ˜¯å‡½æ•°ï¼Œè€Œå®å®šä¹‰ä¸æ‹¬å¼§ä¸çš„â€œå‚æ•°â€ä¹Ÿä¸æ˜¯çœŸçš„傿•°ï¼Œåœ¨å®å±•开的时候对 â€œå‚æ•°â€ 进行的是一对一的替æ¢ã€‚
好处
- æ›´é«˜æ•ˆï¼šå°‘äº†ä¸€æ¬¡è°ƒç”¨é»˜è®¤æž„é€ å‡½æ•°çš„è¿‡ç¨‹ã€‚
- 有些场åˆå¿…é¡»è¦ç”¨åˆå§‹åŒ–列表:
- 叏釿ˆå‘˜ï¼Œå› 为常é‡åªèƒ½åˆå§‹åŒ–ä¸èƒ½èµ‹å€¼ï¼Œæ‰€ä»¥å¿…须放在åˆå§‹åŒ–列表里é¢
- 引用类型,引用必须在定义的时候åˆå§‹åŒ–,并且ä¸èƒ½é‡æ–°èµ‹å€¼ï¼Œæ‰€ä»¥ä¹Ÿè¦å†™åœ¨åˆå§‹åŒ–列表里é¢
- æ²¡æœ‰é»˜è®¤æž„é€ å‡½æ•°çš„ç±»ç±»åž‹ï¼Œå› ä¸ºä½¿ç”¨åˆå§‹åŒ–列表å¯ä»¥ä¸å¿…è°ƒç”¨é»˜è®¤æž„é€ å‡½æ•°æ¥åˆå§‹åŒ–
用花括å·åˆå§‹åŒ–器列表åˆå§‹åŒ–一个对象,其ä¸å¯¹åº”æž„é€ å‡½æ•°æŽ¥å—一个 std::initializer_list
傿•°.
initializer_list 使用
#include <iostream>
#include <vector>
#include <initializer_list>
template <class T>
struct S {
std::vector<T> v;
S(std::initializer_list<T> l) : v(l) {
std::cout << "constructed with a " << l.size() << "-element list\n";
}
void append(std::initializer_list<T> l) {
v.insert(v.end(), l.begin(), l.end());
}
std::pair<const T*, std::size_t> c_arr() const {
return {&v[0], v.size()}; // 在 return è¯å¥ä¸å¤åˆ¶åˆ—表åˆå§‹åŒ–
// è¿™ä¸ä½¿ç”¨ std::initializer_list
}
};
template <typename T>
void templated_fn(T) {}
int main()
{
S<int> s = {1, 2, 3, 4, 5}; // å¤åˆ¶åˆå§‹åŒ–
s.append({6, 7, 8}); // 函数调用ä¸çš„列表åˆå§‹åŒ–
std::cout << "The vector size is now " << s.c_arr().second << " ints:\n";
for (auto n : s.v)
std::cout << n << ' ';
std::cout << '\n';
std::cout << "Range-for over brace-init-list: \n";
for (int x : {-1, -2, -3}) // auto 的规则令æ¤å¸¦èŒƒå›´ for 工作
std::cout << x << ' ';
std::cout << '\n';
auto al = {10, 11, 12}; // auto 的特殊规则
std::cout << "The list bound to auto has size() = " << al.size() << '\n';
// templated_fn({1, 2, 3}); // 编译错误ï¼â€œ {1, 2, 3} â€ä¸æ˜¯è¡¨è¾¾å¼ï¼Œ
// å®ƒæ— ç±»åž‹ï¼Œæ•… T æ— æ³•æŽ¨å¯¼
templated_fn<std::initializer_list<int>>({1, 2, 3}); // OK
templated_fn<std::vector<int>>({1, 2, 3}); // 也 OK
}
é¢å‘对象程åºè®¾è®¡ï¼ˆObject-oriented programming,OOP)是ç§å…·æœ‰å¯¹è±¡æ¦‚念的程åºç¼–ç¨‹å…¸èŒƒï¼ŒåŒæ—¶ä¹Ÿæ˜¯ä¸€ç§ç¨‹åºå¼€å‘的抽象方针。
é¢å‘å¯¹è±¡ä¸‰å¤§ç‰¹å¾ â€”â€” å°è£…ã€ç»§æ‰¿ã€å¤šæ€
把客观事物å°è£…æˆæŠ½è±¡çš„ç±»ï¼Œå¹¶ä¸”ç±»å¯ä»¥æŠŠè‡ªå·±çš„æ•°æ®å’Œæ–¹æ³•åªè®©å¯ä¿¡çš„类或者对象æ“作,对ä¸å¯ä¿¡çš„进行信æ¯éšè—。关键å—:public, protected, private。ä¸å†™é»˜è®¤ä¸º private。
public
æˆå‘˜ï¼šå¯ä»¥è¢«ä»»æ„实体访问protected
æˆå‘˜ï¼šåªå…许被åç±»åŠæœ¬ç±»çš„æˆå‘˜å‡½æ•°è®¿é—®private
æˆå‘˜ï¼šåªå…许被本类的æˆå‘˜å‡½æ•°ã€å‹å…ƒç±»æˆ–å‹å…ƒå‡½æ•°è®¿é—®
- 基类(父类)——> 派生类(å类)
- 多æ€ï¼Œå³å¤šç§çжæ€ï¼ˆå½¢æ€ï¼‰ã€‚ç®€å•æ¥è¯´ï¼Œæˆ‘们å¯ä»¥å°†å¤šæ€å®šä¹‰ä¸ºæ¶ˆæ¯ä»¥å¤šç§å½¢å¼æ˜¾ç¤ºçš„能力。
- å¤šæ€æ˜¯ä»¥å°è£…和继承为基础的。
- C++ 多æ€åˆ†ç±»åŠå®žçŽ°ï¼š
- é‡è½½å¤šæ€ï¼ˆAd-hoc Polymorphism,编译期):函数é‡è½½ã€è¿ç®—符é‡è½½
- å类型多æ€ï¼ˆSubtype Polymorphism,è¿è¡ŒæœŸï¼‰ï¼šè™šå‡½æ•°
- 傿•°å¤šæ€æ€§ï¼ˆParametric Polymorphism,编译期):类模æ¿ã€å‡½æ•°æ¨¡æ¿
- 强制多æ€ï¼ˆCoercion Polymorphism,编译期/è¿è¡ŒæœŸï¼‰ï¼šåŸºæœ¬ç±»åž‹è½¬æ¢ã€è‡ªå®šä¹‰ç±»åž‹è½¬æ¢
函数é‡è½½
class A
{
public:
void do(int a);
void do(int a, int b);
};
- 虚函数:用 virtual 修饰æˆå‘˜å‡½æ•°ï¼Œä½¿å…¶æˆä¸ºè™šå‡½æ•°
- 动æ€ç»‘定:当使用基类的引用或指针调用一个虚函数时将å‘生动æ€ç»‘定
注æ„:
- å¯ä»¥å°†æ´¾ç”Ÿç±»çš„对象赋值给基类的指针或引用,å之ä¸å¯
- 普通函数(éžç±»æˆå‘˜å‡½æ•°ï¼‰ä¸èƒ½æ˜¯è™šå‡½æ•°
- 陿€å‡½æ•°ï¼ˆstatic)ä¸èƒ½æ˜¯è™šå‡½æ•°
- æž„é€ å‡½æ•°ä¸èƒ½æ˜¯è™šå‡½æ•°ï¼ˆå› ä¸ºåœ¨è°ƒç”¨æž„é€ å‡½æ•°æ—¶ï¼Œè™šè¡¨æŒ‡é’ˆå¹¶æ²¡æœ‰åœ¨å¯¹è±¡çš„å†…å˜ç©ºé—´ä¸ï¼Œå¿…é¡»è¦æž„é€ å‡½æ•°è°ƒç”¨å®ŒæˆåŽæ‰ä¼šå½¢æˆè™šè¡¨æŒ‡é’ˆï¼‰
- 内è”函数ä¸èƒ½æ˜¯è¡¨çŽ°å¤šæ€æ€§æ—¶çš„虚函数,解释è§ï¼šè™šå‡½æ•°ï¼ˆvirtual)å¯ä»¥æ˜¯å†…è”函数(inline)å—?
动æ€å¤šæ€ä½¿ç”¨
class Shape // 形状类
{
public:
virtual double calcArea()
{
...
}
virtual ~Shape();
};
class Circle : public Shape // 圆形类
{
public:
virtual double calcArea();
...
};
class Rect : public Shape // 矩形类
{
public:
virtual double calcArea();
...
};
int main()
{
Shape * shape1 = new Circle(4.0);
Shape * shape2 = new Rect(5.0, 6.0);
shape1->calcArea(); // 调用圆形类里é¢çš„æ–¹æ³•
shape2->calcArea(); // 调用矩形类里é¢çš„æ–¹æ³•
delete shape1;
shape1 = nullptr;
delete shape2;
shape2 = nullptr;
return 0;
}
è™šæžæž„å‡½æ•°æ˜¯ä¸ºäº†è§£å†³åŸºç±»çš„æŒ‡é’ˆæŒ‡å‘æ´¾ç”Ÿç±»å¯¹è±¡ï¼Œå¹¶ç”¨åŸºç±»çš„æŒ‡é’ˆåˆ 除派生类对象。
è™šæžæž„函数使用
class Shape
{
public:
Shape(); // æž„é€ å‡½æ•°ä¸èƒ½æ˜¯è™šå‡½æ•°
virtual double calcArea();
virtual ~Shape(); // è™šæžæž„函数
};
class Circle : public Shape // 圆形类
{
public:
virtual double calcArea();
...
};
int main()
{
Shape * shape1 = new Circle(4.0);
shape1->calcArea();
delete shape1; // å› ä¸ºShapeæœ‰è™šæžæž„函数,所以deleteé‡Šæ”¾å†…å˜æ—¶ï¼Œå…ˆè°ƒç”¨åç±»æžæž„函数,å†è°ƒç”¨åŸºç±»æžæž„函数,防æ¢å†…å˜æ³„æ¼ã€‚
shape1 = NULL;
return 0ï¼›
}
纯虚函数是一ç§ç‰¹æ®Šçš„虚函数,在基类ä¸ä¸èƒ½å¯¹è™šå‡½æ•°ç»™å‡ºæœ‰æ„义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去åšã€‚
virtual int A() = 0;
- 类里如果声明了虚函数,这个函数是实现的,哪怕是空实现,它的作用就是为了能让这个函数在它的å类里é¢å¯ä»¥è¢«è¦†ç›–(overrideï¼‰ï¼Œè¿™æ ·çš„è¯ï¼Œç¼–译器就å¯ä»¥ä½¿ç”¨åŽæœŸç»‘定æ¥è¾¾åˆ°å¤šæ€äº†ã€‚çº¯è™šå‡½æ•°åªæ˜¯ä¸€ä¸ªæŽ¥å£ï¼Œæ˜¯ä¸ªå‡½æ•°çš„声明而已,它è¦ç•™åˆ°å类里去实现。
- 虚函数在å类里é¢å¯ä»¥ä¸é‡å†™ï¼›ä½†çº¯è™šå‡½æ•°å¿…须在å类实现æ‰å¯ä»¥å®žä¾‹åŒ–å类。
- 虚函数的类用于 “实作继承â€ï¼Œç»§æ‰¿æŽ¥å£çš„åŒæ—¶ä¹Ÿç»§æ‰¿äº†çˆ¶ç±»çš„实现。纯虚函数关注的是接å£çš„统一性,实现由å类完æˆã€‚
- å¸¦çº¯è™šå‡½æ•°çš„ç±»å«æŠ½è±¡ç±»ï¼Œè¿™ç§ç±»ä¸èƒ½ç›´æŽ¥ç”Ÿæˆå¯¹è±¡ï¼Œè€Œåªæœ‰è¢«ç»§æ‰¿ï¼Œå¹¶é‡å†™å…¶è™šå‡½æ•°åŽï¼Œæ‰èƒ½ä½¿ç”¨ã€‚抽象类被继承åŽï¼Œåç±»å¯ä»¥ç»§ç»æ˜¯æŠ½è±¡ç±»ï¼Œä¹Ÿå¯ä»¥æ˜¯æ™®é€šç±»ã€‚
- 虚基类是虚继承ä¸çš„基类,具体è§ä¸‹æ–‡è™šç»§æ‰¿ã€‚
- è™šå‡½æ•°æŒ‡é’ˆï¼šåœ¨å«æœ‰è™šå‡½æ•°ç±»çš„对象ä¸ï¼ŒæŒ‡å‘虚函数表,在è¿è¡Œæ—¶ç¡®å®šã€‚
- 虚函数表:在程åºåªè¯»æ•°æ®æ®µï¼ˆ
.rodata section
,è§ï¼šç›®æ ‡æ–‡ä»¶å˜å‚¨ç»“æž„ï¼‰ï¼Œå˜æ”¾è™šå‡½æ•°æŒ‡é’ˆï¼Œå¦‚果派生类实现了基类的æŸä¸ªè™šå‡½æ•°ï¼Œåˆ™åœ¨è™šè¡¨ä¸è¦†ç›–åŽŸæœ¬åŸºç±»çš„é‚£ä¸ªè™šå‡½æ•°æŒ‡é’ˆï¼Œåœ¨ç¼–è¯‘æ—¶æ ¹æ®ç±»çš„声明创建。
C++ä¸çš„虚函数(表)实现机制以åŠç”¨Cè¯è¨€å¯¹å…¶è¿›è¡Œçš„æ¨¡æ‹Ÿå®žçް
虚继承用于解决多继承æ¡ä»¶ä¸‹çš„è±å½¢ç»§æ‰¿é—®é¢˜ï¼ˆæµªè´¹å˜å‚¨ç©ºé—´ã€å˜åœ¨äºŒä¹‰æ€§ï¼‰ã€‚
底层实现原ç†ä¸Žç¼–译器相关,一般通过虚基类指针和虚基类表实现,æ¯ä¸ªè™šç»§æ‰¿çš„å类都有一个虚基类指针(å 用一个指针的å˜å‚¨ç©ºé—´ï¼Œ4å—节)和虚基类表(ä¸å 用类对象的å˜å‚¨ç©ºé—´ï¼‰ï¼ˆéœ€è¦å¼ºè°ƒçš„æ˜¯ï¼Œè™šåŸºç±»ä¾æ—§ä¼šåœ¨å类里é¢å˜åœ¨æ‹·è´ï¼Œåªæ˜¯ä»…仅最多å˜åœ¨ä¸€ä»½è€Œå·²ï¼Œå¹¶ä¸æ˜¯ä¸åœ¨å类里é¢äº†ï¼‰ï¼›å½“虚继承的å类被当åšçˆ¶ç±»ç»§æ‰¿æ—¶ï¼Œè™šåŸºç±»æŒ‡é’ˆä¹Ÿä¼šè¢«ç»§æ‰¿ã€‚
实际上,vbptr 指的是虚基类表指针(virtual base table pointer),该指针指å‘了一个虚基类表(virtual table),虚表ä¸è®°å½•了虚基类与本类的å移地å€ï¼›é€šè¿‡å移地å€ï¼Œè¿™æ ·å°±æ‰¾åˆ°äº†è™šåŸºç±»æˆå‘˜ï¼Œè€Œè™šç»§æ‰¿ä¹Ÿä¸ç”¨åƒæ™®é€šå¤šç»§æ‰¿é‚£æ ·ç»´æŒç€å…¬å…±åŸºç±»ï¼ˆè™šåŸºç±»ï¼‰çš„ä¸¤ä»½åŒæ ·çš„æ‹·è´ï¼ŒèŠ‚çœäº†å˜å‚¨ç©ºé—´ã€‚
- 相åŒä¹‹å¤„:都利用了虚指针(å‡å 用类的å˜å‚¨ç©ºé—´ï¼‰å’Œè™šè¡¨ï¼ˆå‡ä¸å 用类的å˜å‚¨ç©ºé—´ï¼‰
- ä¸åŒä¹‹å¤„:
- 虚继承
- è™šåŸºç±»ä¾æ—§å˜åœ¨ç»§æ‰¿ç±»ä¸ï¼Œåªå 用å˜å‚¨ç©ºé—´
- 虚基类表å˜å‚¨çš„æ˜¯è™šåŸºç±»ç›¸å¯¹ç›´æŽ¥ç»§æ‰¿ç±»çš„åç§»
- 虚函数
- 虚函数ä¸å 用å˜å‚¨ç©ºé—´
- 虚函数表å˜å‚¨çš„æ˜¯è™šå‡½æ•°åœ°å€
- 虚继承
- 类模æ¿ä¸å¯ä»¥ä½¿ç”¨è™šå‡½æ•°
- ä¸€ä¸ªç±»ï¼ˆæ— è®ºæ˜¯æ™®é€šç±»è¿˜æ˜¯ç±»æ¨¡æ¿ï¼‰çš„æˆå‘˜æ¨¡æ¿ï¼ˆæœ¬èº«æ˜¯æ¨¡æ¿çš„æˆå‘˜å‡½æ•°ï¼‰ä¸èƒ½æ˜¯è™šå‡½æ•°
- æŠ½è±¡ç±»ï¼šå«æœ‰çº¯è™šå‡½æ•°çš„ç±»
- 接å£ç±»ï¼šä»…嫿œ‰çº¯è™šå‡½æ•°çš„æŠ½è±¡ç±»
- èšåˆç±»ï¼šç”¨æˆ·å¯ä»¥ç›´æŽ¥è®¿é—®å…¶æˆå‘˜ï¼Œå¹¶ä¸”具有特殊的åˆå§‹åŒ–è¯æ³•å½¢å¼ã€‚满足如下特点:
- 所有æˆå‘˜éƒ½æ˜¯ public
- æ²¡æœ‰å®šä¹‰ä»»ä½•æž„é€ å‡½æ•°
- 没有类内åˆå§‹åŒ–
- 没有基类,也没有 virtual 函数
- malloc:申请指定å—节数的内å˜ã€‚申请到的内å˜ä¸çš„åˆå§‹å€¼ä¸ç¡®å®šã€‚
- calloc:为指定长度的对象,分é…能容纳其指定个数的内å˜ã€‚申请到的内å˜çš„æ¯ä¸€ä½ï¼ˆbit)都åˆå§‹åŒ–为 0。
- realloc:更改以å‰åˆ†é…的内å˜é•¿åº¦ï¼ˆå¢žåŠ æˆ–å‡å°‘ï¼‰ã€‚å½“å¢žåŠ é•¿åº¦æ—¶ï¼Œå¯èƒ½éœ€å°†ä»¥å‰åˆ†é…区的内容移到å¦ä¸€ä¸ªè¶³å¤Ÿå¤§çš„区域,而新增区域内的åˆå§‹å€¼åˆ™ä¸ç¡®å®šã€‚
- allocaï¼šåœ¨æ ˆä¸Šç”³è¯·å†…å˜ã€‚程åºåœ¨å‡ºæ ˆçš„æ—¶å€™ï¼Œä¼šè‡ªåŠ¨é‡Šæ”¾å†…å˜ã€‚ä½†æ˜¯éœ€è¦æ³¨æ„的是,alloca ä¸å…·å¯ç§»æ¤æ€§, è€Œä¸”åœ¨æ²¡æœ‰ä¼ ç»Ÿå †æ ˆçš„æœºå™¨ä¸Šå¾ˆéš¾å®žçŽ°ã€‚alloca ä¸å®œä½¿ç”¨åœ¨å¿…须广泛移æ¤çš„程åºä¸ã€‚C99 䏿”¯æŒå˜é•¿æ•°ç»„ (VLA),å¯ä»¥ç”¨æ¥æ›¿ä»£ alloca。
用于分é…ã€é‡Šæ”¾å†…å˜
mallocã€free 使用
申请内å˜ï¼Œç¡®è®¤æ˜¯å¦ç”³è¯·æˆåŠŸ
char *str = (char*) malloc(100);
assert(str != nullptr);
释放内å˜åŽæŒ‡é’ˆç½®ç©º
free(p);
p = nullptr;
- new / new[]:完æˆä¸¤ä»¶äº‹ï¼Œå…ˆåº•层调用 malloc 分é…了内å˜ï¼Œç„¶åŽè°ƒç”¨æž„é€ å‡½æ•°ï¼ˆåˆ›å»ºå¯¹è±¡ï¼‰ã€‚
- delete/delete[]:也完æˆä¸¤ä»¶äº‹ï¼Œå…ˆè°ƒç”¨æžæž„函数(清ç†èµ„æºï¼‰ï¼Œç„¶åŽåº•层调用 free 释放空间。
- new åœ¨ç”³è¯·å†…å˜æ—¶ä¼šè‡ªåŠ¨è®¡ç®—æ‰€éœ€å—节数,而 malloc 则需我们自己输入申请内å˜ç©ºé—´çš„å—节数。
newã€delete 使用
申请内å˜ï¼Œç¡®è®¤æ˜¯å¦ç”³è¯·æˆåŠŸ
int main()
{
T* t = new T(); // 先内å˜åˆ†é… ï¼Œå†æž„é€ å‡½æ•°
delete t; // å…ˆæžæž„函数,å†å†…å˜é‡Šæ”¾
return 0;
}
å®šä½ new(placement new)å…è®¸æˆ‘ä»¬å‘ new ä¼ é€’é¢å¤–的地å€å‚数,从而在预先指定的内å˜åŒºåŸŸåˆ›å»ºå¯¹è±¡ã€‚
new (place_address) type
new (place_address) type (initializers)
new (place_address) type [size]
new (place_address) type [size] { braced initializer list }
place_address
是个指针initializers
æä¾›ä¸€ä¸ªï¼ˆå¯èƒ½ä¸ºç©ºçš„)以逗å·åˆ†éš”çš„åˆå§‹å€¼åˆ—表
Is it legal (and moral) for a member function to say delete this?
åˆæ³•,但:
- å¿…é¡»ä¿è¯ this 对象是通过
new
ï¼ˆä¸æ˜¯new[]
ã€ä¸æ˜¯ placement newã€ä¸æ˜¯æ ˆä¸Šã€ä¸æ˜¯å…¨å±€ã€ä¸æ˜¯å…¶ä»–对象æˆå‘˜ï¼‰åˆ†é…çš„ - å¿…é¡»ä¿è¯è°ƒç”¨
delete this
çš„æˆå‘˜å‡½æ•°æ˜¯æœ€åŽä¸€ä¸ªè°ƒç”¨ this çš„æˆå‘˜å‡½æ•° - å¿…é¡»ä¿è¯æˆå‘˜å‡½æ•°çš„
delete this
åŽé¢æ²¡æœ‰è°ƒç”¨ this 了 - å¿…é¡»ä¿è¯
delete this
åŽæ²¡æœ‰äººä½¿ç”¨äº†
如何定义一个åªèƒ½åœ¨å †ä¸Šï¼ˆæ ˆä¸Šï¼‰ç”Ÿæˆå¯¹è±¡çš„ç±»?
æ–¹æ³•ï¼šå°†æžæž„å‡½æ•°è®¾ç½®ä¸ºç§æœ‰
åŽŸå› ï¼šC++ æ˜¯é™æ€ç»‘定è¯è¨€ï¼Œç¼–è¯‘å™¨ç®¡ç†æ ˆä¸Šå¯¹è±¡çš„ç”Ÿå‘½å‘¨æœŸï¼Œç¼–è¯‘å™¨åœ¨ä¸ºç±»å¯¹è±¡åˆ†é…æ ˆç©ºé—´æ—¶ï¼Œä¼šå…ˆæ£€æŸ¥ç±»çš„æžæž„å‡½æ•°çš„è®¿é—®æ€§ã€‚è‹¥æžæž„函数ä¸å¯è®¿é—®ï¼Œåˆ™ä¸èƒ½åœ¨æ ˆä¸Šåˆ›å»ºå¯¹è±¡ã€‚
方法:将 new å’Œ delete é‡è½½ä¸ºç§æœ‰
åŽŸå› ï¼šåœ¨å †ä¸Šç”Ÿæˆå¯¹è±¡ï¼Œä½¿ç”¨ new å…³é”®è¯æ“作,其过程分为两阶段:第一阶段,使用 new åœ¨å †ä¸Šå¯»æ‰¾å¯ç”¨å†…å˜ï¼Œåˆ†é…ç»™å¯¹è±¡ï¼›ç¬¬äºŒé˜¶æ®µï¼Œè°ƒç”¨æž„é€ å‡½æ•°ç”Ÿæˆå¯¹è±¡ã€‚å°† new æ“ä½œè®¾ç½®ä¸ºç§æœ‰ï¼Œé‚£ä¹ˆç¬¬ä¸€é˜¶æ®µå°±æ— 法完æˆï¼Œå°±ä¸èƒ½å¤Ÿåœ¨å †ä¸Šç”Ÿæˆå¯¹è±¡ã€‚
头文件:#include <memory>
std::auto_ptr<std::string> ps (new std::string(str))ï¼›
- shared_ptr
- unique_ptr
- weak_ptr
- auto_ptr(被 C++11 弃用)
- Class shared_ptr å®žçŽ°å…±äº«å¼æ‹¥æœ‰ï¼ˆshared ownership)概念。多个智能指针指å‘相åŒå¯¹è±¡ï¼Œè¯ 10000 ¥å¯¹è±¡å’Œå…¶ç›¸å…³èµ„æºä¼šåœ¨ “最åŽä¸€ä¸ª reference 被销æ¯â€ æ—¶è¢«é‡Šæ”¾ã€‚ä¸ºäº†åœ¨ç»“æž„è¾ƒå¤æ‚çš„æƒ…æ™¯ä¸æ‰§è¡Œä¸Šè¿°å·¥ä½œï¼Œæ ‡å‡†åº“æä¾› weak_ptrã€bad_weak_ptr å’Œ enable_shared_from_this ç‰è¾…助类。
- Class unique_ptr 实现独å 弿‹¥æœ‰ï¼ˆexclusive ownershipï¼‰æˆ–ä¸¥æ ¼æ‹¥æœ‰ï¼ˆstrict ownership)概念,ä¿è¯åŒä¸€æ—¶é—´å†…åªæœ‰ä¸€ä¸ªæ™ºèƒ½æŒ‡é’ˆå¯ä»¥æŒ‡å‘è¯¥å¯¹è±¡ã€‚ä½ å¯ä»¥ç§»äº¤æ‹¥æœ‰æƒã€‚它对于é¿å…å†…å˜æ³„æ¼ï¼ˆresource leak)——如 new åŽå¿˜è®° delete ——特别有用。
多个智能指针å¯ä»¥å…±äº«åŒä¸€ä¸ªå¯¹è±¡ï¼Œå¯¹è±¡çš„æœ€æœ«ä¸€ä¸ªæ‹¥æœ‰ç€æœ‰è´£ä»»é”€æ¯å¯¹è±¡ï¼Œå¹¶æ¸…ç†ä¸Žè¯¥å¯¹è±¡ç›¸å…³çš„æ‰€æœ‰èµ„æºã€‚
- 支æŒå®šåˆ¶åž‹åˆ 除器(custom deleter),å¯é˜²èŒƒ Cross-DLL 问题(对象在动æ€é“¾æŽ¥åº“(DLL)ä¸è¢« new 创建,å´åœ¨å¦ä¸€ä¸ª DLL 内被 delete 销æ¯ï¼‰ã€è‡ªåŠ¨è§£é™¤äº’æ–¥é”
weak_ptr å…è®¸ä½ å…±äº«ä½†ä¸æ‹¥æœ‰æŸå¯¹è±¡ï¼Œä¸€æ—¦æœ€æœ«ä¸€ä¸ªæ‹¥æœ‰è¯¥å¯¹è±¡çš„æ™ºèƒ½æŒ‡é’ˆå¤±åŽ»äº†æ‰€æœ‰æƒï¼Œä»»ä½• weak_ptr 都会自动æˆç©ºï¼ˆemptyï¼‰ã€‚å› æ¤ï¼Œåœ¨ default å’Œ copy æž„é€ å‡½æ•°ä¹‹å¤–ï¼Œweak_ptr åªæä¾› “接å—一个 shared_ptrâ€ çš„æž„é€ å‡½æ•°ã€‚
- 坿‰“ç ´çŽ¯çŠ¶å¼•ç”¨ï¼ˆcycles of referencesï¼Œä¸¤ä¸ªå…¶å®žå·²ç»æ²¡æœ‰è¢«ä½¿ç”¨çš„对象彼æ¤äº’指,使之看似还在 “被使用†的状æ€ï¼‰çš„问题
unique_ptr 是 C++11 æ‰å¼€å§‹æä¾›çš„类型,是一ç§åœ¨å¼‚常时å¯ä»¥å¸®åŠ©é¿å…èµ„æºæ³„æ¼çš„æ™ºèƒ½æŒ‡é’ˆã€‚采用独å 弿‹¥æœ‰ï¼Œæ„味ç€å¯ä»¥ç¡®ä¿ä¸€ä¸ªå¯¹è±¡å’Œå…¶ç›¸åº”的资æºåŒä¸€æ—¶é—´åªè¢«ä¸€ä¸ª pointer 拥有。一旦拥有ç€è¢«é”€æ¯æˆ–编程 empty,或开始拥有å¦ä¸€ä¸ªå¯¹è±¡ï¼Œå…ˆå‰æ‹¥æœ‰çš„那个对象就会被销æ¯ï¼Œå…¶ä»»ä½•相应资æºäº¦ä¼šè¢«é‡Šæ”¾ã€‚
- unique_ptr 用于å–代 auto_ptr
被 c++11 å¼ƒç”¨ï¼ŒåŽŸå› æ˜¯ç¼ºä¹è¯è¨€ç‰¹æ€§å¦‚ â€œé’ˆå¯¹æž„é€ å’Œèµ‹å€¼â€ çš„ std::move
è¯ä¹‰ï¼Œä»¥åŠå…¶ä»–瑕疵。
- auto_ptr å¯ä»¥èµ‹å€¼æ‹·è´ï¼Œå¤åˆ¶æ‹·è´åŽæ‰€æœ‰æƒè½¬ç§»ï¼›unqiue_ptr æ— æ‹·è´èµ‹å€¼è¯ä¹‰ï¼Œä½†å®žçŽ°äº†
move
è¯ä¹‰ï¼› - auto_ptr 对象ä¸èƒ½ç®¡ç†æ•°ç»„ï¼ˆæžæž„调用
delete
),unique_ptr å¯ä»¥ç®¡ç†æ•°ç»„ï¼ˆæžæž„调用delete[]
);
- 用于éžå¤šæ€ç±»åž‹çš„转æ¢
- 䏿‰§è¡Œè¿è¡Œæ—¶ç±»åž‹æ£€æŸ¥ï¼ˆè½¬æ¢å®‰å…¨æ€§ä¸å¦‚ dynamic_cast)
- é€šå¸¸ç”¨äºŽè½¬æ¢æ•°å€¼æ•°æ®ç±»åž‹ï¼ˆå¦‚ float -> int)
- å¯ä»¥åœ¨æ•´ä¸ªç±»å±‚次结构ä¸ç§»åŠ¨æŒ‡é’ˆï¼Œå类转化为父类安全(å‘上转æ¢ï¼‰ï¼Œçˆ¶ç±»è½¬åŒ–为åç±»ä¸å®‰å…¨ï¼ˆå› 为åç±»å¯èƒ½æœ‰ä¸åœ¨çˆ¶ç±»çš„å—æ®µæˆ–方法)
å‘ä¸Šè½¬æ¢æ˜¯ä¸€ç§éšå¼è½¬æ¢ã€‚
- 用于多æ€ç±»åž‹çš„转æ¢
- 执行行è¿è¡Œæ—¶ç±»åž‹æ£€æŸ¥
- åªé€‚用于指针或引用
- 坹䏿˜Žç¡®çš„æŒ‡é’ˆçš„转æ¢å°†å¤±è´¥ï¼ˆè¿”回 nullptr),但ä¸å¼•å‘异常
- å¯ä»¥åœ¨æ•´ä¸ªç±»å±‚次结构ä¸ç§»åŠ¨æŒ‡é’ˆï¼ŒåŒ…æ‹¬å‘上转æ¢ã€å‘下转æ¢
- ç”¨äºŽåˆ é™¤ constã€volatile å’Œ __unaligned 特性(如将 const int 类型转æ¢ä¸º int 类型 )
- 用于ä½çš„简å•釿–°è§£é‡Š
- 滥用 reinterpret_cast è¿ç®—符å¯èƒ½å¾ˆå®¹æ˜“带æ¥é£Žé™©ã€‚ é™¤éžæ‰€éœ€è½¬æ¢æœ¬èº«æ˜¯ä½Žçº§åˆ«çš„,å¦åˆ™åº”使用其他强制转æ¢è¿ç®—符之一。
- å…许将任何指针转æ¢ä¸ºä»»ä½•其他指针类型(如
char*
到int*
或One_class*
到Unrelated_class*
之类的转æ¢ï¼Œä½†å…¶æœ¬èº«å¹¶ä¸å®‰å…¨ï¼‰ - 也å…许将任何整数类型转æ¢ä¸ºä»»ä½•指针类型以åŠåå‘转æ¢ã€‚
- reinterpret_cast è¿ç®—符ä¸èƒ½ä¸¢æŽ‰ constã€volatile 或 __unaligned 特性。
- reinterpret_cast 的一个实际用途是在哈希函数ä¸ï¼Œå³ï¼Œé€šè¿‡è®©ä¸¤ä¸ªä¸åŒçš„å€¼å‡ ä¹Žä¸ä»¥ç›¸åŒçš„索引结尾的方å¼å°†å€¼æ˜ 射到索引。
- 由于强制转æ¢ä¸ºå¼•用类型失败,dynamic_cast è¿ç®—ç¬¦å¼•å‘ bad_cast 异常。
bad_cast 使用
try {
Circle& ref_circle = dynamic_cast<Circle&>(ref_shape);
}
catch (bad_cast b) {
cout << "Caught: " << b.what();
}
- 用于多æ€ç±»åž‹çš„转æ¢
- typeid è¿ç®—符å…许在è¿è¡Œæ—¶ç¡®å®šå¯¹è±¡çš„类型
- type_id 返回一个 type_info 对象的引用
- 如果想通过基类的指针获得派生类的数æ®ç±»åž‹ï¼ŒåŸºç±»å¿…须带有虚函数
- åªèƒ½èŽ·å–对象的实际类型
- type_info ç±»æè¿°ç¼–译器在程åºä¸ç”Ÿæˆçš„类型信æ¯ã€‚ æ¤ç±»çš„对象å¯ä»¥æœ‰æ•ˆå˜å‚¨æŒ‡å‘类型的å称的指针。 type_info 类还å¯å˜å‚¨é€‚åˆæ¯”较两个类型是å¦ç›¸ç‰æˆ–比较其排列顺åºçš„ç¼–ç 值。 类型的编ç è§„åˆ™å’ŒæŽ’åˆ—é¡ºåºæ˜¯æœªæŒ‡å®šçš„,并且å¯èƒ½å› 程åºè€Œå¼‚。
- 头文件:
typeinfo
typeidã€type_info 使用
#include <iostream>
using namespace std;
class Flyable // 能飞的
{
public:
virtual void takeoff() = 0; // 起飞
virtual void land() = 0; // é™è½
};
class Bird : public Flyable // 鸟
{
public:
void foraging() {...} // 觅食
virtual void takeoff() {...}
virtual void land() {...}
virtual ~Bird(){}
};
class Plane : public Flyable // 飞机
{
public:
void carry() {...} // è¿è¾“
virtual void takeoff() {...}
virtual void land() {...}
};
class type_info
{
public:
const char* name() const;
bool operator == (const type_info & rhs) const;
bool operator != (const type_info & rhs) const;
int before(const type_info & rhs) const;
virtual ~type_info();
private:
...
};
void doSomething(Flyable *obj) // åšäº›äº‹æƒ…
{
obj->takeoff();
cout << typeid(*obj).name() << endl; // è¾“å‡ºä¼ å…¥å¯¹è±¡ç±»åž‹ï¼ˆ"class Bird" or "class Plane")
if(typeid(*obj) == typeid(Bird)) // 判æ–对象类型
{
Bird *bird = dynamic_cast<Bird *>(obj); // 对象转化
bird->foraging();
}
obj->land();
}
int main(){
Bird *b = new Bird();
doSomething(b);
delete b;
b = nullptr;
return 0;
}
- 视 C++ 为一个è¯è¨€è”邦(Cã€Object-Oriented C++ã€Template C++ã€STL)
- å®å¯ä»¥ç¼–译器替æ¢é¢„处ç†å™¨ï¼ˆå°½é‡ä»¥
const
ã€enum
ã€inline
替æ¢#define
) - å°½å¯èƒ½ä½¿ç”¨ const
- 确定对象被使用å‰å·²å…ˆè¢«åˆå§‹åŒ–ï¼ˆæž„é€ æ—¶èµ‹å€¼ï¼ˆcopy æž„é€ å‡½æ•°ï¼‰æ¯” default æž„é€ åŽèµ‹å€¼ï¼ˆcopy assignment)效率高)
- 了解 C++ 默默编写并调用哪些函数(编译器暗自为 class 创建 default æž„é€ å‡½æ•°ã€copy æž„é€ å‡½æ•°ã€copy assignment æ“ä½œç¬¦ã€æžæž„函数)
- è‹¥ä¸æƒ³ä½¿ç”¨ç¼–译器自动生æˆçš„函数,就应该明确拒ç»ï¼ˆå°†ä¸æƒ³ä½¿ç”¨çš„æˆå‘˜å‡½æ•°å£°æ˜Žä¸º private,并且ä¸äºˆå®žçŽ°ï¼‰
- 为多æ€åŸºç±»å£°æ˜Ž virtual æžæž„函数(如果 class 带有任何 virtual 函数,它就应该拥有一个 virtual æžæž„函数)
- åˆ«è®©å¼‚å¸¸é€ƒç¦»æžæž„å‡½æ•°ï¼ˆæžæž„函数应该åžä¸‹ä¸ä¼ æ’异常,或者结æŸç¨‹åºï¼Œè€Œä¸æ˜¯å出异常;如果è¦å¤„ç†å¼‚å¸¸åº”è¯¥åœ¨éžæžæž„的普通函数处ç†ï¼‰
- ç»ä¸åœ¨æž„é€ å’Œæžæž„过程ä¸è°ƒç”¨ virtual å‡½æ•°ï¼ˆå› ä¸ºè¿™ç±»è°ƒç”¨ä»Žä¸ä¸‹é™è‡³ derived class)
- 令
operator=
返回一个reference to *this
(用于连é”赋值) - 在
operator=
ä¸å¤„ç† â€œè‡ªæˆ‘èµ‹å€¼â€ - 赋值对象时应确ä¿å¤åˆ¶ “对象内的所有æˆå‘˜å˜é‡â€ åŠ â€œæ‰€æœ‰ base class æˆåˆ†â€ï¼ˆè°ƒç”¨åŸºç±»å¤åˆ¶æž„é€ å‡½æ•°ï¼‰
- 以对象管ç†èµ„æºï¼ˆèµ„æºåœ¨æž„é€ å‡½æ•°èŽ·å¾—ï¼Œåœ¨æžæž„函数释放,建议使用智能指针,资æºå–得时机便是åˆå§‹åŒ–时机(Resource Acquisition Is Initialization,RAII))
- 在资æºç®¡ç†ç±»ä¸å°å¿ƒ copying 行为(普éçš„ RAII class copying 行为是:抑制 copyingã€å¼•ç”¨è®¡æ•°ã€æ·±åº¦æ‹·è´ã€è½¬ç§»åº•éƒ¨èµ„æºæ‹¥æœ‰æƒï¼ˆç±»ä¼¼ auto_ptr))
- 在资æºç®¡ç†ç±»ä¸æä¾›å¯¹åŽŸå§‹èµ„æºï¼ˆraw resources)的访问(对原始资æºçš„访问å¯èƒ½ç»è¿‡æ˜¾å¼è½¬æ¢æˆ–éšå¼è½¬æ¢ï¼Œä¸€èˆ¬è€Œè¨€æ˜¾ç¤ºè½¬æ¢æ¯”较安全,éšå¼è½¬æ¢å¯¹å®¢æˆ·æ¯”较方便)
- æˆå¯¹ä½¿ç”¨ new å’Œ delete æ—¶è¦é‡‡å–相åŒå½¢å¼ï¼ˆ
new
ä¸ä½¿ç”¨[]
则delete []
,new
ä¸ä¸ä½¿ç”¨[]
则delete
) - 以独立è¯å¥å°† newed 对象å˜å‚¨äºŽï¼ˆç½®å…¥ï¼‰æ™ºèƒ½æŒ‡é’ˆï¼ˆå¦‚æžœä¸è¿™æ ·åšï¼Œå¯èƒ½ä¼šå› ä¸ºç¼–è¯‘å™¨ä¼˜åŒ–ï¼Œå¯¼è‡´éš¾ä»¥å¯Ÿè§‰çš„èµ„æºæ³„æ¼ï¼‰
- 让接å£å®¹æ˜“被æ£ç¡®ä½¿ç”¨ï¼Œä¸æ˜“被误用(促进æ£å¸¸ä½¿ç”¨çš„办法:接å£çš„一致性ã€å†…置类型的行为兼容;阻æ¢è¯¯ç”¨çš„办法:建立新类型,é™åˆ¶ç±»åž‹ä¸Šçš„æ“ä½œï¼Œçº¦æŸå¯¹è±¡å€¼ã€æ¶ˆé™¤å®¢æˆ·çš„资æºç®¡ç†è´£ä»»ï¼‰
- 设计 class 犹如设计 type,需è¦è€ƒè™‘对象创建ã€é”€æ¯ã€åˆå§‹åŒ–ã€èµ‹å€¼ã€å€¼ä¼ 递ã€åˆæ³•值ã€ç»§æ‰¿å…³ç³»ã€è½¬æ¢ã€ä¸€èˆ¬åŒ–ç‰ç‰ã€‚
- å®ä»¥ pass-by-reference-to-const æ›¿æ¢ pass-by-value (å‰è€…通常更高效ã€é¿å…切割问题(slicing problem),但ä¸é€‚用于内置类型ã€STLè¿ä»£å™¨ã€å‡½æ•°å¯¹è±¡ï¼‰
- 必须返回对象时,别妄想返回其 reference(ç»ä¸è¿”回 pointer 或 reference 指å‘一个 local stack 对象,或返回 reference 指å‘一个 heap-allocated 对象,或返回 pointer 或 reference 指å‘一个 local static 对象而有å¯èƒ½åŒæ—¶éœ€è¦å¤šä¸ªè¿™æ ·çš„对象。)
- å°†æˆå‘˜å˜é‡å£°æ˜Žä¸º private(为了å°è£…ã€ä¸€è‡´æ€§ã€å¯¹å…¶è¯»å†™ç²¾ç¡®æŽ§åˆ¶ç‰ï¼‰
- å®ä»¥ non-memberã€non-friend æ›¿æ¢ member 函数(å¯å¢žåŠ å°è£…性ã€åŒ…裹弹性(packaging flexibilityï¼‰ã€æœºèƒ½æ‰©å……性)
- è‹¥æ‰€æœ‰å‚æ•°ï¼ˆåŒ…括被this指针所指的那个éšå–»å‚数)皆须è¦ç±»åž‹è½¬æ¢ï¼Œè¯·ä¸ºæ¤é‡‡ç”¨ non-member 函数
- è€ƒè™‘å†™ä¸€ä¸ªä¸æŠ›å¼‚å¸¸çš„ swap 函数
- å°½å¯èƒ½å»¶åŽå˜é‡å®šä¹‰å¼çš„出现时间(å¯å¢žåŠ ç¨‹åºæ¸…æ™°åº¦å¹¶æ”¹å–„ç¨‹åºæ•ˆçŽ‡ï¼‰
- å°½é‡å°‘åšè½¬åž‹åŠ¨ä½œï¼ˆæ—§å¼ï¼š
(T)expression
ã€T(expression)
;新å¼ï¼šconst_cast<T>(expression)
ã€dynamic_cast<T>(expression)
ã€reinterpret_cast<T>(expression)
ã€static_cast<T>(expression)
ã€ï¼›å°½é‡é¿å…è½¬åž‹ã€æ³¨é‡æ•ˆçއé¿å… dynamic_castsã€å°½é‡è®¾è®¡æˆæ— 需转型ã€å¯æŠŠè½¬åž‹å°è£…æˆå‡½æ•°ã€å®å¯ç”¨æ–°å¼è½¬åž‹ï¼‰ - é¿å…使用 handles(包括 å¼•ç”¨ã€æŒ‡é’ˆã€è¿ä»£å™¨ï¼‰æŒ‡å‘å¯¹è±¡å†…éƒ¨ï¼ˆä»¥å¢žåŠ å°è£…性ã€ä½¿ const æˆå‘˜å‡½æ•°çš„è¡Œä¸ºæ›´åƒ constã€é™ä½Ž “虚åŠå·ç 牌â€ï¼ˆdangling handles,如悬空指针ç‰ï¼‰çš„å¯èƒ½æ€§ï¼‰
- 为 “异常安全†而努力是值得的(异常安全函数(Exception-safe functions)å³ä½¿å‘生异常也ä¸ä¼šæ³„éœ²èµ„æºæˆ–å…许任何数æ®ç»“构败å,分为三ç§å¯èƒ½çš„ä¿è¯ï¼šåŸºæœ¬åž‹ã€å¼ºåˆ—åž‹ã€ä¸æŠ›å¼‚常型)
- é€å½»äº†è§£ inlining 的里里外外(inlining 在大多数 C++ 程åºä¸æ˜¯ç¼–译期的行为;inline 函数是å¦çœŸæ£ inline,å–决于编译器;大部分编译器拒ç»å¤ªè¿‡å¤æ‚(如带有循环或递归)的函数 inlining,而所有对 virtual å‡½æ•°çš„è°ƒç”¨ï¼ˆé™¤éžæ˜¯æœ€å¹³æ·¡æ— 奇的)也都会使 inlining è½ç©ºï¼›inline é€ æˆçš„代ç 膨胀å¯èƒ½å¸¦æ¥æ•ˆçއæŸå¤±ï¼›inline å‡½æ•°æ— æ³•éšç€ç¨‹åºåº“çš„å‡çº§è€Œå‡çº§ï¼‰
- 将文件间的编译ä¾å˜å…³ç³»é™è‡³æœ€ä½Žï¼ˆå¦‚果使用 object references 或 object pointers å¯ä»¥å®Œæˆä»»åŠ¡ï¼Œå°±ä¸è¦ä½¿ç”¨ objects;如果能够,尽é‡ä»¥ class å£°æ˜Žå¼æ›¿æ¢ class 定义å¼ï¼›ä¸ºå£°æ˜Žå¼å’Œå®šä¹‰å¼æä¾›ä¸åŒçš„头文件)
- ç¡®å®šä½ çš„ public 继承塑模出 is-a(是一ç§ï¼‰å…³ç³»ï¼ˆé€‚用于 base classes 身上的æ¯ä¸€ä»¶äº‹æƒ…一定适用于 derived classes èº«ä¸Šï¼Œå› ä¸ºæ¯ä¸€ä¸ª derived class 对象也都是一个 base class 对象)
- é¿å…é®æŽ©ç»§æ‰¿è€Œæ¥çš„åå—(å¯ä½¿ç”¨ using å£°æ˜Žå¼æˆ–转交函数(forwarding functions)æ¥è®©è¢«é®æŽ©çš„åå—å†è§å¤©æ—¥ï¼‰
- 区分接å£ç»§æ‰¿å’Œå®žçŽ°ç»§æ‰¿ï¼ˆåœ¨ public 继承之下,derived classes 总是继承 base class 的接å£ï¼›pure virtual 函数åªå…·ä½“指定接å£ç»§æ‰¿ï¼›éžçº¯ impure virtual 函数具体指定接å£ç»§æ‰¿åŠç¼ºçœå®žçŽ°ç»§æ‰¿ï¼›non-virtual 函数具体指定接å£ç»§æ‰¿ä»¥åŠå¼ºåˆ¶æ€§å®žçŽ°ç»§æ‰¿ï¼‰
- 考虑 virtual 函数以外的其他选择(如 Template Method 设计模å¼çš„ non-virtual interface(NVI)手法,将 virtual 函数替æ¢ä¸º “函数指针æˆå‘˜å˜é‡â€ï¼Œä»¥
tr1::function
æˆå‘˜å˜é‡æ›¿æ¢ virtual 函数,将继承体系内的 virtual 函数替æ¢ä¸ºå¦ä¸€ä¸ªç»§æ‰¿ä½“系内的 virtual 函数) - ç»ä¸é‡æ–°å®šä¹‰ç»§æ‰¿è€Œæ¥çš„ non-virtual 函数
- ç»ä¸é‡æ–°å®šä¹‰ç»§æ‰¿è€Œæ¥çš„缺çœå‚æ•°å€¼ï¼Œå› ä¸ºç¼ºçœå‚æ•°å€¼æ˜¯é™æ€ç»‘定(statically bound),而 virtual å‡½æ•°å´æ˜¯åЍæ€ç»‘定(dynamically bound)
- 通过å¤åˆå¡‘模 has-a(有一个)或 â€œæ ¹æ®æŸç‰©å®žçŽ°å‡ºâ€ï¼ˆåœ¨åº”用域(application domain),å¤åˆæ„味 has-a(有一个);在实现域(implementation domain),å¤åˆæ„å‘³ç€ is-implemented-in-terms-ofï¼ˆæ ¹æ®æŸç‰©å®žçŽ°å‡ºï¼‰ï¼‰
- 明智而审慎地使用 private 继承(private 继承æ„å‘³ç€ is-implemented-in-terms-ofï¼ˆæ ¹æ®æŸç‰©å®žçŽ°å‡ºï¼‰ï¼Œå°½å¯èƒ½ä½¿ç”¨å¤åˆï¼Œå½“ derived class 需è¦è®¿é—® protected base class çš„æˆå‘˜ï¼Œæˆ–需è¦é‡æ–°å®šä¹‰ç»§æ‰¿è€Œæ¥çš„æ—¶å€™ virtual å‡½æ•°ï¼Œæˆ–éœ€è¦ empty base 最优化时,æ‰ä½¿ç”¨ private 继承)
- 明智而审慎地使用多é‡ç»§æ‰¿ï¼ˆå¤šç»§æ‰¿æ¯”å•ä¸€ç»§æ‰¿å¤æ‚,å¯èƒ½å¯¼è‡´æ–°çš„æ§ä¹‰æ€§ï¼Œä»¥åŠå¯¹ virtual 继承的需è¦ï¼Œä½†ç¡®æœ‰æ£å½“用途,如 “public 继承æŸä¸ª interface class†和 “private 继承æŸä¸ªå助实现的 classâ€ï¼›virtual 继承å¯è§£å†³å¤šç»§æ‰¿ä¸‹è±å½¢ç»§æ‰¿çš„äºŒä¹‰æ€§é—®é¢˜ï¼Œä½†ä¼šå¢žåŠ å¤§å°ã€é€Ÿåº¦ã€åˆå§‹åŒ–åŠèµ‹å€¼çš„夿‚度ç‰ç‰æˆæœ¬ï¼‰
- 了解éšå¼æŽ¥å£å’Œç¼–译期多æ€ï¼ˆclass å’Œ templates éƒ½æ”¯æŒæŽ¥å£ï¼ˆinterfaces)和多æ€ï¼ˆpolymorphism);class çš„æŽ¥å£æ˜¯ä»¥ç¾å为ä¸å¿ƒçš„æ˜¾å¼çš„(explicit),多æ€åˆ™æ˜¯é€šè¿‡ virtual 函数å‘生于è¿è¡ŒæœŸï¼›template çš„æŽ¥å£æ˜¯å¥ 基于有效表达å¼çš„éšå¼çš„(implicit),多æ€åˆ™æ˜¯é€šè¿‡ template 具现化和函数é‡è½½è§£æžï¼ˆfunction overloading resolution)å‘生于编译期)
- 了解 typename çš„åŒé‡æ„义(声明 template ç±»åž‹å‚æ•°æ˜¯ï¼Œå‰ç¼€å…³é”®å— class å’Œ typename çš„æ„义完全相åŒï¼›è¯·ä½¿ç”¨å…³é”®å— typename æ ‡è¯†åµŒå¥—ä»Žå±žç±»åž‹å称,但ä¸å¾—在基类列(base class lists)或æˆå‘˜åˆå€¼åˆ—(member initialization list)内以它作为 base class 修饰符)
- å¦ä¹ å¤„ç†æ¨¡æ¿åŒ–基类内的å称(å¯åœ¨ derived class templates 内通过
this->
指涉 base class templates 内的æˆå‘˜å称,或藉由一个明白写出的 “base class èµ„æ ¼ä¿®é¥°ç¬¦â€ å®Œæˆï¼‰ - å°†ä¸Žå‚æ•°æ— å…³çš„ä»£ç æŠ½ç¦» templatesï¼ˆå› ç±»åž‹æ¨¡æ¿å‚数(non-type template parametersï¼‰è€Œé€ æˆä»£ç 膨胀往往å¯ä»¥é€šè¿‡å‡½æ•°å‚数或 class æˆå‘˜å˜é‡æ›¿æ¢ template 傿•°æ¥æ¶ˆé™¤ï¼›å› ç±»åž‹å‚æ•°ï¼ˆtype parametersï¼‰è€Œé€ æˆçš„代ç 膨胀往往å¯ä»¥é€šè¿‡è®©å¸¦æœ‰å®Œå…¨ç›¸åŒäºŒè¿›åˆ¶è¡¨è¿°ï¼ˆbinary representations)的实现类型(instantiation types)共享实现ç )
- è¿ç”¨æˆå‘˜å‡½æ•°æ¨¡æ¿æŽ¥å—所有兼容类型(请使用æˆå‘˜å‡½æ•°æ¨¡æ¿ï¼ˆmember function templatesï¼‰ç”Ÿæˆ â€œå¯æŽ¥å—æ‰€æœ‰å…¼å®¹ç±»åž‹â€ 的函数;声明 member templates 用于 “泛化 copy æž„é€ â€ æˆ– “泛化 assignment æ“作†时还需è¦å£°æ˜Žæ£å¸¸çš„ copy æž„é€ å‡½æ•°å’Œ copy assignment æ“作符)
- 需è¦ç±»åž‹è½¬æ¢æ—¶è¯·ä¸ºæ¨¡æ¿å®šä¹‰éžæˆå‘˜å‡½æ•°ï¼ˆå½“我们编写一个 class template,而它所æä¾›ä¹‹ â€œä¸Žæ¤ template ç›¸å…³çš„â€ å‡½æ•°æ”¯æŒ â€œæ‰€æœ‰å‚æ•°ä¹‹éšå¼ç±»åž‹è½¬æ¢â€ 时,请将那些函数定义为 “class template 内部的 friend 函数â€ï¼‰
- 请使用 traits classes 表现类型信æ¯ï¼ˆtraits classes 通过 templates å’Œ “templates 特化†使得 “类型相关信æ¯â€ 在编译期å¯ç”¨ï¼Œé€šè¿‡é‡è½½æŠ€æœ¯ï¼ˆoverloading)实现在编译期对类型执行 if...else 测试)
- 认识 template 元编程(模æ¿å…ƒç¼–程(TMP,template metaprogramming)å¯å°†å·¥ä½œç”±è¿è¡ŒæœŸç§»å¾€ç¼–è¯‘æœŸï¼Œå› æ¤å¾—以实现早期错误侦测和更高的执行效率;TMP å¯è¢«ç”¨æ¥ç”Ÿæˆ “给予政ç–选择组åˆâ€ï¼ˆbased on combinations of policy choices)的客户定制代ç ,也å¯ç”¨æ¥é¿å…生æˆå¯¹æŸäº›ç‰¹æ®Šç±»åž‹å¹¶ä¸é€‚åˆçš„代ç )
- 了解 new-handler 的行为(set_new_handler å…许客户指定一个在内å˜åˆ†é…æ— æ³•èŽ·å¾—æ»¡è¶³æ—¶è¢«è°ƒç”¨çš„å‡½æ•°ï¼›nothrow new 是一个颇具局é™çš„å·¥å…·ï¼Œå› ä¸ºå®ƒåªé€‚用于内å˜åˆ†é…(operator new),åŽç»§çš„æž„é€ å‡½æ•°è°ƒç”¨è¿˜æ˜¯å¯èƒ½æŠ›å‡ºå¼‚常)
- 了解 new å’Œ delete çš„åˆç†æ›¿æ¢æ—¶æœºï¼ˆä¸ºäº†æ£€æµ‹è¿ç”¨é”™è¯¯ã€æ”¶é›†åЍæ€åˆ†é…内å˜ä¹‹ä½¿ç”¨ç»Ÿè®¡ä¿¡æ¯ã€å¢žåŠ åˆ†é…和归还速度ã€é™ä½Žç¼ºçœå†…å˜ç®¡ç†å™¨å¸¦æ¥çš„空间é¢å¤–开销ã€å¼¥è¡¥ç¼ºçœåˆ†é…器ä¸çš„éžæœ€ä½³é½ä½ã€å°†ç›¸å…³å¯¹è±¡æˆç°‡é›†ä¸ã€èŽ·å¾—éžä¼ 统的行为)
- 编写 new å’Œ delete 时需固守常规(operator new åº”è¯¥å†…æ¶µä¸€ä¸ªæ— ç©·å¾ªçŽ¯ï¼Œå¹¶åœ¨å…¶ä¸å°è¯•分é…内å˜ï¼Œå¦‚æžœå®ƒæ— æ³•æ»¡è¶³å†…å˜éœ€æ±‚,就应该调用 new-handlerï¼Œå®ƒä¹Ÿåº”è¯¥æœ‰èƒ½åŠ›å¤„ç† 0 bytes 申请,class ä¸“å±žç‰ˆæœ¬åˆ™è¿˜åº”è¯¥å¤„ç† â€œæ¯”æ£ç¡®å¤§å°æ›´å¤§çš„(错误)申请â€ï¼›operator delete 应该在收到 null 指针时ä¸åšä»»ä½•事,class ä¸“å±žç‰ˆæœ¬åˆ™è¿˜åº”è¯¥å¤„ç† â€œæ¯”æ£ç¡®å¤§å°æ›´å¤§çš„(错误)申请â€ï¼‰
- 写了 placement new 也è¦å†™ placement deleteï¼ˆå½“ä½ å†™ä¸€ä¸ª placement operator new,请确定也写出了对应的 placement operator delete,å¦åˆ™å¯èƒ½ä¼šå‘生éšå¾®è€Œæ—¶æ–æ—¶ç»çš„å†…å˜æ³„æ¼ï¼›å½“ä½ å£°æ˜Ž placement new å’Œ placement delete,请确定ä¸è¦æ— æ„è¯†ï¼ˆéžæ•…æ„ï¼‰åœ°é®æŽ©äº†å®ƒä»¬åœ°æ£å¸¸ç‰ˆæœ¬ï¼‰
- ä¸è¦è½»å¿½ç¼–译器的è¦å‘Š
- 让自己熟悉包括 TR1 åœ¨å†…çš„æ ‡å‡†ç¨‹åºåº“(TR1,C++ Technical Report 1,C++11 æ ‡å‡†çš„è‰ç¨¿æ–‡ä»¶ï¼‰
- 让自己熟悉 Boostï¼ˆå‡†æ ‡å‡†åº“ï¼‰
- 仔细区别 pointers å’Œ referencesï¼ˆå½“ä½ çŸ¥é“ä½ éœ€è¦æŒ‡å‘æŸä¸ªä¸œè¥¿ï¼Œè€Œä¸”ç»ä¸ä¼šæ”¹å˜æŒ‡å‘å…¶ä»–ä¸œè¥¿ï¼Œæˆ–æ˜¯å½“ä½ å®žçŽ°ä¸€ä¸ªæ“ä½œç¬¦è€Œå…¶è¯æ³•éœ€æ±‚æ— æ³•ç”± pointers è¾¾æˆï¼Œä½ 就应该选择 references;任何其他时候,请采用 pointers)
- 最好使用 C++ 转型æ“作符(
static_cast
ã€const_cast
ã€dynamic_cast
ã€reinterpret_cast
) - ç»ä¸è¦ä»¥å¤šæ€ï¼ˆpolymorphically)方å¼å¤„ç†æ•°ç»„(多æ€ï¼ˆpolymorphism)和指针算术ä¸èƒ½æ··ç”¨ï¼›æ•°ç»„å¯¹è±¡å‡ ä¹Žæ€»æ˜¯ä¼šæ¶‰åŠæŒ‡é’ˆçš„算术è¿ç®—,所以数组和多æ€ä¸è¦æ··ç”¨ï¼‰
- éžå¿…è¦ä¸æä¾› default constructor(é¿å…对象ä¸çš„å—æ®µè¢«æ— æ„义地åˆå§‹åŒ–)
- 对定制的 “类型转æ¢å‡½æ•°â€ ä¿æŒè¦è§‰ï¼ˆå•自å˜é‡ constructors å¯é€šè¿‡ç®€æ˜“法(explicit 关键å—)或代ç†ç±»ï¼ˆproxy classes)æ¥é¿å…编译器误用;éšå¼ç±»åž‹è½¬æ¢æ“ä½œç¬¦å¯æ”¹ä¸ºæ˜¾å¼çš„ member function æ¥é¿å…éžé¢„期行为)
- 区别 increment/decrement æ“作符的å‰ç½®ï¼ˆprefix)和åŽç½®ï¼ˆpostfix)形å¼ï¼ˆå‰ç½®å¼ç´¯åŠ åŽå–出,返回一个 referenceï¼›åŽç½®å¼å–出åŽç´¯åŠ ï¼Œè¿”å›žä¸€ä¸ª const 对象;处ç†ç”¨æˆ·å®šåˆ¶ç±»åž‹æ—¶ï¼Œåº”该尽å¯èƒ½ä½¿ç”¨å‰ç½®å¼ incrementï¼›åŽç½®å¼çš„实现应以其å‰ç½®å¼å…„弟为基础)
- åƒä¸‡ä¸è¦é‡è½½
&&
,||
和,
æ“作符(&&
与||
çš„é‡è½½ä¼šç”¨ “函数调用è¯ä¹‰â€ å–代 “骤æ»å¼è¯ä¹‰â€ï¼›,
çš„é‡è½½å¯¼è‡´ä¸èƒ½ä¿è¯å·¦ä¾§è¡¨è¾¾å¼ä¸€å®šæ¯”å³ä¾§è¡¨è¾¾å¼æ›´æ—©è¢«è¯„估) - 了解å„ç§ä¸åŒæ„义的 new å’Œ delete(
new operator
ã€operator new
ã€placement new
ã€operator new[]
ï¼›delete operator
ã€operator delete
ã€destructor
ã€operator delete[]
) - 利用 destructors é¿å…泄æ¼èµ„æºï¼ˆåœ¨ destructors 释放资æºå¯ä»¥é¿å…å¼‚å¸¸æ—¶çš„èµ„æºæ³„æ¼ï¼‰
- 在 constructors 内阻æ¢èµ„æºæ³„æ¼ï¼ˆç”±äºŽ C++ åªä¼šæžæž„å·²æž„é€ å®Œæˆçš„å¯¹è±¡ï¼Œå› æ¤åœ¨æž„é€ å‡½æ•°å¯ä»¥ä½¿ç”¨ try...catch 或者 auto_ptr(以åŠä¸Žä¹‹ç›¸ä¼¼çš„ classes) 处ç†å¼‚å¸¸æ—¶èµ„æºæ³„露问题)
- ç¦æ¢å¼‚常æµå‡º destructors ä¹‹å¤–ï¼ˆåŽŸå› ï¼šä¸€ã€é¿å… terminate 函数在 exception ä¼ æ’è¿‡ç¨‹çš„æ ˆå±•å¼€ï¼ˆstack-unwinding)机制ç§è¢«è°ƒç”¨ï¼›äºŒã€ååŠ©ç¡®ä¿ destructors 完æˆå…¶åº”该完æˆçš„æ‰€æœ‰äº‹æƒ…)
- 了解 “抛出一个 exception†与 â€œä¼ é€’ä¸€ä¸ªå‚æ•°â€ 或 “调用一个虚函数†之间的差异(第一,exception objects 总是会被å¤åˆ¶ï¼ˆby pointer 除外),如果以 by value æ–¹å¼æ•æ‰ç”šè‡³è¢«å¤åˆ¶ä¸¤æ¬¡ï¼Œè€Œä¼ é€’ç»™å‡½æ•°å‚æ•°çš„对象则ä¸ä¸€å®šå¾—å¤åˆ¶ï¼›ç¬¬äºŒï¼Œâ€œè¢«æŠ›å‡ºæˆä¸º exceptions†的对象,其被å…许的类型转æ¢åŠ¨ä½œæ¯” â€œè¢«ä¼ é€’åˆ°å‡½æ•°åŽ»â€ çš„å¯¹è±¡å°‘ï¼›ç¬¬ä¸‰ï¼Œcatch åå¥ä»¥å…¶ “出现于æºä»£ç 的顺åºâ€ 被编译器检验对比,其ä¸ç¬¬ä¸€ä¸ªåŒ¹é…æˆåŠŸè€…ä¾¿æ‰§è¡Œï¼Œè€Œè°ƒç”¨ä¸€ä¸ªè™šå‡½æ•°ï¼Œè¢«é€‰ä¸æ‰§è¡Œçš„æ˜¯é‚£ä¸ª “与对象类型最佳å»åˆâ€ 的函数)
- 以 by reference æ–¹å¼æ•获 exceptions(å¯é¿å…å¯¹è±¡åˆ é™¤é—®é¢˜ã€exception objects 的切割问题,å¯ä¿ç•™æ•æ‰æ ‡å‡† exceptions 的能力,å¯çº¦æŸ exception object 需è¦å¤åˆ¶çš„æ¬¡æ•°ï¼‰
- 明智è¿ç”¨ exception specifications(exception specifications 对 â€œå‡½æ•°å¸Œæœ›æŠ›å‡ºä»€ä¹ˆæ ·çš„ exceptions†æä¾›äº†å“越的说明;也有一些缺点,包括编译器åªå¯¹å®ƒä»¬åšå±€éƒ¨æ€§æ£€éªŒè€Œå¾ˆå®¹æ˜“ä¸ç»æ„地è¿å,与å¯èƒ½ä¼šå¦¨ç¢æ›´ä¸Šå±‚çš„ exception 处ç†å‡½æ•°å¤„ç†æœªé¢„期的 exceptions)
- 了解异常处ç†çš„æˆæœ¬ï¼ˆç²—ç•¥ä¼°è®¡ï¼Œå¦‚æžœä½¿ç”¨ try è¯å¥å—,代ç 大约整体膨胀 5%-10%,执行速度亦大约下é™è¿™ä¸ªæ•°ï¼›å› æ¤è¯·å°†ä½ 对 try è¯å¥å—å’Œ exception specifications 的使用é™åˆ¶äºŽéžç”¨ä¸å¯çš„地点,并且在真æ£å¼‚å¸¸çš„æƒ…å†µä¸‹æ‰æŠ›å‡º exceptions)
- 谨记 80-20 æ³•åˆ™ï¼ˆè½¯ä»¶çš„æ•´ä½“æ€§èƒ½å‡ ä¹Žæ€»æ˜¯ç”±å…¶æž„æˆè¦ç´ (代ç )的一å°éƒ¨åˆ†å†³å®šçš„,å¯ä½¿ç”¨ç¨‹åºåˆ†æžå™¨ï¼ˆprogram profiler)识别出消耗资æºçš„代ç )
- 考虑使用 lazy evaluation(缓å¼è¯„估)(å¯åº”用于:Reference Counting(引用计数)æ¥é¿å…éžå¿…è¦çš„对象å¤åˆ¶ã€åŒºåˆ† operator[] 的读和写动作æ¥åšä¸åŒçš„事情ã€Lazy Fetching(缓å¼å–出)æ¥é¿å…éžå¿…è¦çš„æ•°æ®åº“读å–动作ã€Lazy Expression Evaluation(表达å¼ç¼“评估)æ¥é¿å…éžå¿…è¦çš„æ•°å€¼è®¡ç®—动作)
- åˆ†æœŸæ‘Šè¿˜é¢„æœŸçš„è®¡ç®—æˆæœ¬ï¼ˆå½“ä½ å¿…é¡»æ”¯æŒæŸäº›è¿ç®—è€Œå…¶ç»“æž„å‡ ä¹Žæ€»æ˜¯è¢«éœ€è¦ï¼Œæˆ–其结果常常被多次需è¦çš„æ—¶å€™ï¼Œover-eager evaluation(超急评估)å¯ä»¥æ”¹å–„ç¨‹åºæ•ˆçŽ‡ï¼‰
- 英文:Google C++ Style Guide
- 䏿–‡ï¼šC++ é£Žæ ¼æŒ‡å—
容器 | 底层数æ®ç»“æž„ | æ—¶é—´å¤æ‚度 | æœ‰æ— åº | å¯ä¸å¯é‡å¤ | å…¶ä»– |
---|---|---|---|---|---|
array | 数组 | éšæœºè¯»æ”¹ O(1) | æ— åº | å¯é‡å¤ | 支æŒéšæœºè®¿é—® |
vector | 数组 | éšæœºè¯»æ”¹ã€å°¾éƒ¨æ’å…¥ã€å°¾éƒ¨åˆ 除 O(1) 头部æ’å…¥ã€å¤´éƒ¨åˆ 除 O(n) |
æ— åº | å¯é‡å¤ | 支æŒéšæœºè®¿é—® |
deque | åŒç«¯é˜Ÿåˆ— | 头尾æ’å…¥ã€å¤´å°¾åˆ 除 O(1) | æ— åº | å¯é‡å¤ | 一个ä¸å¤®æŽ§åˆ¶å™¨ + 多个缓冲区,支æŒé¦–å°¾å¿«é€Ÿå¢žåˆ ï¼Œæ”¯æŒéšæœºè®¿é—® |
forward_list | å•å‘链表 | æ’å…¥ã€åˆ 除 O(1) | æ— åº | å¯é‡å¤ | 䏿”¯æŒéšæœºè®¿é—® |
list | åŒå‘链表 | æ’å…¥ã€åˆ 除 O(1) | æ— åº | å¯é‡å¤ | 䏿”¯æŒéšæœºè®¿é—® |
stack | deque / list | 顶部æ’å…¥ã€é¡¶éƒ¨åˆ 除 O(1) | æ— åº | å¯é‡å¤ | deque 或 list å°é—头端开å£ï¼Œä¸ç”¨ vector çš„åŽŸå› åº”è¯¥æ˜¯å®¹é‡å¤§å°æœ‰é™åˆ¶ï¼Œæ‰©å®¹è€—æ—¶ |
queue | deque / list | 尾部æ’å…¥ã€å¤´éƒ¨åˆ 除 O(1) | æ— åº | å¯é‡å¤ | deque 或 list å°é—头端开å£ï¼Œä¸ç”¨ vector çš„åŽŸå› åº”è¯¥æ˜¯å®¹é‡å¤§å°æœ‰é™åˆ¶ï¼Œæ‰©å®¹è€—æ—¶ |
priority_queue | vector + max-heap | æ’å…¥ã€åˆ 除 O(log2n) | æœ‰åº | å¯é‡å¤ | vector容器+heap处ç†è§„则 |
set | çº¢é»‘æ ‘ | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(log2n) | æœ‰åº | ä¸å¯é‡å¤ | |
multiset | çº¢é»‘æ ‘ | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(log2n) | æœ‰åº | å¯é‡å¤ | |
map | çº¢é»‘æ ‘ | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(log2n) | æœ‰åº | ä¸å¯é‡å¤ | |
multimap | çº¢é»‘æ ‘ | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(log2n) | æœ‰åº | å¯é‡å¤ | |
unordered_set | 哈希表 | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(1) 最差 O(n) | æ— åº | ä¸å¯é‡å¤ | |
unordered_multiset | 哈希表 | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(1) 最差 O(n) | æ— åº | å¯é‡å¤ | |
unordered_map | 哈希表 | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(1) 最差 O(n) | æ— åº | ä¸å¯é‡å¤ | |
unordered_multimap | 哈希表 | æ’å…¥ã€åˆ é™¤ã€æŸ¥æ‰¾ O(1) 最差 O(n) | æ— åº | å¯é‡å¤ |
算法 | 底层算法 | æ—¶é—´å¤æ‚度 | å¯ä¸å¯é‡å¤ |
---|---|---|---|
find | é¡ºåºæŸ¥æ‰¾ | O(n) | å¯é‡å¤ |
sort | å†…çœæŽ’åº | O(n*log2n) | å¯é‡å¤ |
é¡ºåºæ ˆæ•°æ®ç»“构和图片
typedef struct {
ElemType *elem;
int top;
int size;
int increment;
} SqStack;
队列数æ®ç»“æž„
typedef struct {
ElemType * elem;
int front;
int rear;
int maxSize;
}SqQueue;
éžå¾ªçŽ¯é˜Ÿåˆ—å›¾ç‰‡
SqQueue.rear++
循环队列图片
SqQueue.rear = (SqQueue.rear + 1) % SqQueue.maxSize
顺åºè¡¨æ•°æ®ç»“构和图片
typedef struct {
ElemType *elem;
int length;
int size;
int increment;
} SqList;
链弿•°æ®ç»“æž„
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
链队列图片
å•链表图片
åŒå‘链表图片
循环链表图片
哈希函数:H(key): K -> D , key ∈ K
- ç›´æŽ¥å®šå€æ³•
- 除留余数法
- æ•°å—åˆ†æžæ³•
- æŠ˜å æ³•
- 平方å–䏿³•
- é“¾åœ°å€æ³•:key 相åŒçš„用å•链表链接
- å¼€æ”¾å®šå€æ³•
- 线性探测法:key ç›¸åŒ -> 放到 key 的下一个ä½ç½®ï¼Œ
Hi = (H(key) + i) % m
- 二次探测法:key ç›¸åŒ -> 放到
Di = 1^2, -1^2, ..., ±(k)^2,(k<=m/2)
- éšæœºæŽ¢æµ‹æ³•:
H = (H(key) + ä¼ªéšæœºæ•°) % m
- 线性探测法:key ç›¸åŒ -> 放到 key 的下一个ä½ç½®ï¼Œ
线性探测的哈希表数æ®ç»“构和图片
typedef char KeyType;
typedef struct {
KeyType key;
}RcdType;
typedef struct {
RcdType *rcd;
int size;
int count;
bool *tag;
}HashTable;
函数直接或间接地调用自身
- 分治法
- 问题的分解
- 问题规模的分解
- æŠ˜åŠæŸ¥æ‰¾ï¼ˆé€’归)
- 归并排åºï¼ˆé€’归)
- 快速排åºï¼ˆé€’归)
- è¿ä»£ï¼šåå¤åˆ©ç”¨å˜é‡æ—§å€¼æŽ¨å‡ºæ–°å€¼
- æŠ˜åŠæŸ¥æ‰¾ï¼ˆè¿ä»£ï¼‰
- 归并排åºï¼ˆè¿ä»£ï¼‰
广义表的头尾链表å˜å‚¨è¡¨ç¤ºå’Œå›¾ç‰‡
// 广义表的头尾链表å˜å‚¨è¡¨ç¤º
typedef enum {ATOM, LIST} ElemTag;
// ATOM==0:原å,LIST==1:å表
typedef struct GLNode {
ElemTag tag;
// 公共部分,用于区分原å结点和表结点
union {
// 原å结点和表结点的è”åˆéƒ¨åˆ†
AtomType atom;
// atom 是原å结点的值域,AtomType 由用户定义
struct {
struct GLNode *hp, *tp;
} ptr;
// ptr 是表结点的指针域,prt.hp å’Œ ptr.tp 分别指å‘表头和表尾
} a;
} *GList, GLNode;
扩展线性链表å˜å‚¨è¡¨ç¤ºå’Œå›¾ç‰‡
// 广义表的扩展线性链表å˜å‚¨è¡¨ç¤º
typedef enum {ATOM, LIST} ElemTag;
// ATOM==0:原å,LIST==1:å表
typedef struct GLNode1 {
ElemTag tag;
// 公共部分,用于区分原å结点和表结点
union {
// 原å结点和表结点的è”åˆéƒ¨åˆ†
AtomType atom; // 原å结点的值域
struct GLNode1 *hp; // 表结点的表头指针
} a;
struct GLNode1 *tp;
// 相当于线性链表的 next,指å‘ä¸‹ä¸€ä¸ªå…ƒç´ ç»“ç‚¹
} *GList1, GLNode1;
- éžç©ºäºŒå‰æ ‘第 i 层最多 2(i-1) 个结点 (i >= 1)
- 深度为 k çš„äºŒå‰æ ‘最多 2k - 1 个结点 (k >= 1)
- 度为 0 的结点数为 n0,度为 2 的结点数为 n2,则 n0 = n2 + 1
- 有 n ä¸ªç»“ç‚¹çš„å®Œå…¨äºŒå‰æ ‘深度 k = ⌊ log2(n) ⌋ + 1
- å¯¹äºŽå« n ä¸ªç»“ç‚¹çš„å®Œå…¨äºŒå‰æ ‘ä¸ç¼–å·ä¸º i (1 <= i <= n) 的结点
- è‹¥ i = 1ï¼Œä¸ºæ ¹ï¼Œå¦åˆ™åŒäº²ä¸º ⌊ i / 2 ⌋
- è‹¥ 2i > n,则 i 结点没有左å©å,å¦åˆ™å©åç¼–å·ä¸º 2i
- è‹¥ 2i + 1 > n,则 i 结点没有å³å©å,å¦åˆ™å©åç¼–å·ä¸º 2i + 1
äºŒå‰æ ‘æ•°æ®ç»“æž„
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
äºŒå‰æ ‘顺åºå˜å‚¨å›¾ç‰‡
äºŒå‰æ ‘链å¼å˜å‚¨å›¾ç‰‡
- å…ˆåºé历
- ä¸åºé历
- åŽç»é历
- 层次é历
- æ»¡äºŒå‰æ ‘
- å®Œå…¨äºŒå‰æ ‘ï¼ˆå †ï¼‰
- å¤§é¡¶å †ï¼šæ ¹ >= å·¦ && æ ¹ >= å³
- å°é¡¶å †ï¼šæ ¹ <= å·¦ && æ ¹ <= å³
- äºŒå‰æŸ¥æ‰¾æ ‘ï¼ˆäºŒå‰æŽ’åºæ ‘):左 < æ ¹ < å³
- å¹³è¡¡äºŒå‰æ ‘(AVLæ ‘ï¼‰ï¼š| å·¦åæ ‘æ ‘é«˜ - å³åæ ‘æ ‘é«˜ | <= 1
- 最å°å¤±è¡¡æ ‘ï¼šå¹³è¡¡äºŒå‰æ ‘æ’å…¥æ–°ç»“ç‚¹å¯¼è‡´å¤±è¡¡çš„åæ ‘:调整:
- LLåž‹ï¼šæ ¹çš„å·¦å©å峿—‹
- RRåž‹ï¼šæ ¹çš„å³å©å左旋
- LRåž‹ï¼šæ ¹çš„å·¦å©å左旋,å†å³æ—‹
- RL型:å³å©åçš„å·¦åæ ‘ï¼Œå…ˆå³æ—‹ï¼Œå†å·¦æ—‹
- åŒäº²è¡¨ç¤ºæ³•
- åŒäº²å©å表示法
- å©å兄弟表示法
一ç§ä¸ç›¸äº¤çš„å集所构æˆçš„é›†åˆ S = {S1, S2, ..., Sn}
- | å·¦åæ ‘æ ‘é«˜ - å³åæ ‘æ ‘é«˜ | <= 1
- å¹³è¡¡äºŒå‰æ ‘å¿…å®šæ˜¯äºŒå‰æœç´¢æ ‘,å之则ä¸ä¸€å®š
- 最å°äºŒå‰å¹³è¡¡æ ‘的节点的公å¼ï¼š
F(n)=F(n-1)+F(n-2)+1
(1 æ˜¯æ ¹èŠ‚ç‚¹ï¼ŒF(n-1) æ˜¯å·¦åæ ‘的节点数é‡ï¼ŒF(n-2) 是å³åæ ‘çš„èŠ‚ç‚¹æ•°é‡ï¼‰
å¹³è¡¡äºŒå‰æ ‘图片
å¹³è¡¡äºŒå‰æ ‘æ’å…¥æ–°ç»“ç‚¹å¯¼è‡´å¤±è¡¡çš„åæ ‘
调整:
- LL åž‹ï¼šæ ¹çš„å·¦å©å峿—‹
- RR åž‹ï¼šæ ¹çš„å³å©å左旋
- LR åž‹ï¼šæ ¹çš„å·¦å©å左旋,å†å³æ—‹
- RL 型:å³å©åçš„å·¦åæ ‘ï¼Œå…ˆå³æ—‹ï¼Œå†å·¦æ—‹
- 节点是红色或黑色。
- æ ¹æ˜¯é»‘è‰²ã€‚
- 所有å¶å都是黑色(å¶å是 NIL 节点)。
- æ¯ä¸ªçº¢è‰²èŠ‚ç‚¹å¿…é¡»æœ‰ä¸¤ä¸ªé»‘è‰²çš„å节点。(从æ¯ä¸ªå¶ååˆ°æ ¹çš„æ‰€æœ‰è·¯å¾„ä¸Šä¸èƒ½æœ‰ä¸¤ä¸ªè¿žç»çš„红色节点。)(新增节点的父节点必须相åŒï¼‰
- 从任一节点到其æ¯ä¸ªå¶å的所有简å•路径都包å«ç›¸åŒæ•°ç›®çš„黑色节点。(新增节点必须为红)
- å˜è‰²
- 左旋
- 峿—‹
- å…³è”æ•°ç»„:如 STL ä¸çš„ mapã€set
- çº¢é»‘æ ‘çš„æ·±åº¦æ¯”è¾ƒå¤§ï¼Œè€Œ B æ ‘å’Œ B+ æ ‘çš„æ·±åº¦åˆ™ç›¸å¯¹è¦å°ä¸€äº›
- B+ æ ‘åˆ™å°†æ•°æ®éƒ½ä¿å˜åœ¨å¶åèŠ‚ç‚¹ï¼ŒåŒæ—¶é€šè¿‡é“¾è¡¨çš„å½¢å¼å°†ä»–们连接在一起。
B æ ‘ã€B+ æ ‘å›¾ç‰‡
- ä¸€èˆ¬åŒ–çš„äºŒå‰æŸ¥æ‰¾æ ‘(binary search tree)
- “矮胖â€ï¼Œå†…部(éžå¶å)节点å¯ä»¥æ‹¥æœ‰å¯å˜æ•°é‡çš„å节点(数é‡èŒƒå›´é¢„先定义好)
- å¤§éƒ¨åˆ†æ–‡ä»¶ç³»ç»Ÿã€æ•°æ®åº“系统都采用Bæ ‘ã€B+æ ‘ä½œä¸ºç´¢å¼•ç»“æž„
- B+æ ‘ä¸åªæœ‰å¶å节点会带有指å‘记录的指针(ROWID),而Bæ ‘åˆ™æ‰€æœ‰èŠ‚ç‚¹éƒ½å¸¦æœ‰ï¼Œåœ¨å†…éƒ¨èŠ‚ç‚¹å‡ºçŽ°çš„ç´¢å¼•é¡¹ä¸ä¼šå†å‡ºçŽ°åœ¨å¶å节点ä¸ã€‚
- B+æ ‘ä¸æ‰€æœ‰å¶å节点都是通过指针连接在一起,而Bæ ‘ä¸ä¼šã€‚
对于在内部节点的数æ®ï¼Œå¯ç›´æŽ¥å¾—到,ä¸å¿…æ ¹æ®å¶å节点æ¥å®šä½ã€‚
- éžå¶å节点ä¸ä¼šå¸¦ä¸Š ROWIDï¼Œè¿™æ ·ï¼Œä¸€ä¸ªå—ä¸å¯ä»¥å®¹çº³æ›´å¤šçš„索引项,一是å¯ä»¥é™ä½Žæ ‘的高度。二是一个内部节点å¯ä»¥å®šä½æ›´å¤šçš„å¶å节点。
- å¶å节点之间通过指针æ¥è¿žæŽ¥ï¼ŒèŒƒå›´æ‰«æå°†å分简å•,而对于Bæ ‘æ¥è¯´ï¼Œåˆ™éœ€è¦åœ¨å¶å节点和内部节点ä¸åœçš„往返移动。
B æ ‘ã€B+ æ ‘åŒºåˆ«æ¥è‡ªï¼šdifferences-between-b-trees-and-b-treesã€Bæ ‘å’ŒB+æ ‘çš„åŒºåˆ«
八剿 ‘图片
八剿 ‘(octreeï¼‰ï¼Œæˆ–ç§°å…«å…ƒæ ‘ï¼Œæ˜¯ä¸€ç§ç”¨äºŽæè¿°ä¸‰ç»´ç©ºé—´ï¼ˆåˆ’åˆ†ç©ºé—´ï¼‰çš„æ ‘çŠ¶æ•°æ®ç»“æž„ã€‚å…«å‰æ ‘çš„æ¯ä¸ªèŠ‚ç‚¹è¡¨ç¤ºä¸€ä¸ªæ£æ–¹ä½“çš„ä½“ç§¯å…ƒç´ ï¼Œæ¯ä¸ªèŠ‚ç‚¹æœ‰å…«ä¸ªå节点,这八个åèŠ‚ç‚¹æ‰€è¡¨ç¤ºçš„ä½“ç§¯å…ƒç´ åŠ åœ¨ä¸€èµ·å°±ç‰äºŽçˆ¶èŠ‚ç‚¹çš„ä½“ç§¯ã€‚ä¸€èˆ¬ä¸å¿ƒç‚¹ä½œä¸ºèŠ‚ç‚¹çš„åˆ†å‰ä¸å¿ƒã€‚
- 三维计算机图形
- 最邻近æœç´¢
排åºç®—法 | 平凿—¶é—´å¤æ‚度 | æœ€å·®æ—¶é—´å¤æ‚度 | ç©ºé—´å¤æ‚度 | æ•°æ®å¯¹è±¡ç¨³å®šæ€§ |
---|---|---|---|---|
å†’æ³¡æŽ’åº | O(n2) | O(n2) | O(1) | 稳定 |
é€‰æ‹©æŽ’åº | O(n2) | O(n2) | O(1) | 数组ä¸ç¨³å®šã€é“¾è¡¨ç¨³å®š |
æ’å…¥æŽ’åº | O(n2) | O(n2) | O(1) | 稳定 |
å¿«é€ŸæŽ’åº | O(n*log2n) | O(n2) | O(log2n) | ä¸ç¨³å®š |
å †æŽ’åº | O(n*log2n) | O(n*log2n) | O(1) | ä¸ç¨³å®š |
å½’å¹¶æŽ’åº | O(n*log2n) | O(n*log2n) | O(n) | 稳定 |
å¸Œå°”æŽ’åº | O(n*log2n) | O(n2) | O(1) | ä¸ç¨³å®š |
è®¡æ•°æŽ’åº | O(n+m) | O(n+m) | O(n+m) | 稳定 |
æ¡¶æŽ’åº | O(n) | O(n) | O(m) | 稳定 |
åŸºæ•°æŽ’åº | O(k*n) | O(n2) | 稳定 |
- 凿Œ‰ä»Žå°åˆ°å¤§æŽ’列
- k:代表数值ä¸çš„ “数ä½â€ 个数
- n:代表数æ®è§„模
- m:代表数æ®çš„æœ€å¤§å€¼å‡æœ€å°å€¼
- æ¥è‡ªï¼šwikipedia . 排åºç®—法
查找算法 | 平凿—¶é—´å¤æ‚度 | ç©ºé—´å¤æ‚度 | 查找æ¡ä»¶ |
---|---|---|---|
é¡ºåºæŸ¥æ‰¾ | O(n) | O(1) | æ— åºæˆ–æœ‰åº |
äºŒåˆ†æŸ¥æ‰¾ï¼ˆæŠ˜åŠæŸ¥æ‰¾ï¼‰ | O(log2n) | O(1) | æœ‰åº |
æ’值查找 | O(log2(log2n)) | O(1) | æœ‰åº |
æ–æ³¢é‚£å¥‘查找 | O(log2n) | O(1) | æœ‰åº |
哈希查找 | O(1) | O(n) | æ— åºæˆ–æœ‰åº |
äºŒå‰æŸ¥æ‰¾æ ‘ï¼ˆäºŒå‰æœç´¢æ ‘查找) | O(log2n) | ||
çº¢é»‘æ ‘ | O(log2n) | ||
2-3æ ‘ | O(log2n - log3n) | ||
Bæ ‘/B+æ ‘ | O(log2n) |
图æœç´¢ç®—法 | æ•°æ®ç»“æž„ | éåŽ†æ—¶é—´å¤æ‚度 | ç©ºé—´å¤æ‚度 |
---|---|---|---|
BFS广度优先æœç´¢ | 邻接矩阵 邻接链表 |
O(|v|2) O(|v|+|E|) |
O(|v|2) O(|v|+|E|) |
DFS深度优先æœç´¢ | 邻接矩阵 邻接链表 |
O(|v|2) O(|v|+|E|) |
O(|v|2) O(|v|+|E|) |
算法 | æ€æƒ³ | 应用 |
---|---|---|
分治法 | æŠŠä¸€ä¸ªå¤æ‚的问题分æˆä¸¤ä¸ªæˆ–æ›´å¤šçš„ç›¸åŒæˆ–相似的å问题,直到最åŽå问题å¯ä»¥ç®€å•的直接求解,原问题的解å³å问题的解的åˆå¹¶ | å¾ªçŽ¯èµ›æ—¥ç¨‹å®‰æŽ’é—®é¢˜ã€æŽ’åºç®—法(快速排åºã€å½’并排åºï¼‰ |
动æ€è§„划 | 通过把原问题分解为相对简å•çš„åé—®é¢˜çš„æ–¹å¼æ±‚è§£å¤æ‚问题的方法,适用于有é‡å å问题和最优å结构性质的问题 | èƒŒåŒ…é—®é¢˜ã€æ–波那契数列 |
贪心法 | 一ç§åœ¨æ¯ä¸€æ¥é€‰æ‹©ä¸éƒ½é‡‡å–在当å‰çжæ€ä¸‹æœ€å¥½æˆ–æœ€ä¼˜ï¼ˆå³æœ€æœ‰åˆ©ï¼‰çš„选择,从而希望导致结果是最好或最优的算法 | 旅行推销员问题(最çŸè·¯å¾„é—®é¢˜ï¼‰ã€æœ€å°ç”Ÿæˆæ ‘ã€å“ˆå¤«æ›¼ç¼–ç |
- Chessboard Coverage Problem(棋盘覆盖问题)
- Knapsack Problem(背包问题)
- Neumann Neighbor Problemï¼ˆå†¯è¯ºä¾æ›¼é‚»å±…问题)
- Round Robin Problem(循环赛日程安排问题)
- Tubing Problem(输油管é“问题)
对于有线程系统:
- 进程是资æºåˆ†é…的独立å•ä½
- 线程是资æºè°ƒåº¦çš„独立å•ä½
å¯¹äºŽæ— çº¿ç¨‹ç³»ç»Ÿï¼š
- 进程是资æºè°ƒåº¦ã€åˆ†é…的独立å•ä½
- 管é“(PIPE)
- 有å管é“:一ç§åŠåŒå·¥çš„通信方å¼ï¼Œå®ƒå…è®¸æ— äº²ç¼˜å…³ç³»è¿›ç¨‹é—´çš„é€šä¿¡
- 优点:å¯ä»¥å®žçް任æ„关系的进程间的通信
- 缺点:
- 长期å˜äºŽç³»ç»Ÿä¸ï¼Œä½¿ç”¨ä¸å½“容易出错
- 缓冲区有é™
- æ— å管é“:一ç§åŠåŒå·¥çš„通信方å¼ï¼Œåªèƒ½åœ¨å…·æœ‰äº²ç¼˜å…³ç³»çš„进程间使用(父å进程)
- ä¼˜ç‚¹ï¼šç®€å•æ–¹ä¾¿
- 缺点:
- å±€é™äºŽå•å‘通信
- åªèƒ½åˆ›å»ºåœ¨å®ƒçš„进程以åŠå…¶æœ‰äº²ç¼˜å…³ç³»çš„进程之间
- 缓冲区有é™
- 有å管é“:一ç§åŠåŒå·¥çš„通信方å¼ï¼Œå®ƒå…è®¸æ— äº²ç¼˜å…³ç³»è¿›ç¨‹é—´çš„é€šä¿¡
- ä¿¡å·é‡ï¼ˆSemaphore):一个计数器,å¯ä»¥ç”¨æ¥æŽ§åˆ¶å¤šä¸ªçº¿ç¨‹å¯¹å…±äº«èµ„æºçš„访问
- 优点:å¯ä»¥åŒæ¥è¿›ç¨‹
- 缺点:信å·é‡æœ‰é™
- ä¿¡å·ï¼ˆSignalï¼‰ï¼šä¸€ç§æ¯”è¾ƒå¤æ‚的通信方å¼ï¼Œç”¨äºŽé€šçŸ¥æŽ¥æ”¶è¿›ç¨‹æŸä¸ªäº‹ä»¶å·²ç»å‘生
- 消æ¯é˜Ÿåˆ—(Message Queue):是消æ¯çš„é“¾è¡¨ï¼Œå˜æ”¾åœ¨å†…æ ¸ä¸å¹¶ç”±æ¶ˆæ¯é˜Ÿåˆ—æ ‡è¯†ç¬¦æ ‡è¯†
- 优点:å¯ä»¥å®žçް任æ„进程间的通信,并通过系统调用函数æ¥å®žçŽ°æ¶ˆæ¯å‘é€å’ŒæŽ¥æ”¶ä¹‹é—´çš„åŒæ¥ï¼Œæ— éœ€è€ƒè™‘åŒæ¥é—®é¢˜ï¼Œæ–¹ä¾¿
- 缺点:信æ¯çš„å¤åˆ¶éœ€è¦é¢å¤–消耗 CPU 的时间,ä¸é€‚宜于信æ¯é‡å¤§æˆ–æ“作频ç¹çš„场åˆ
- 共享内å˜ï¼ˆShared Memoryï¼‰ï¼šæ˜ å°„ä¸€æ®µèƒ½è¢«å…¶ä»–è¿›ç¨‹æ‰€è®¿é—®çš„å†…å˜ï¼Œè¿™æ®µå…±äº«å†…å˜ç”±ä¸€ä¸ªè¿›ç¨‹åˆ›å»ºï¼Œä½†å¤šä¸ªè¿›ç¨‹éƒ½å¯ä»¥è®¿é—®
- ä¼˜ç‚¹ï¼šæ— é¡»å¤åˆ¶ï¼Œå¿«æ·ï¼Œä¿¡æ¯é‡å¤§
- 缺点:
- é€šä¿¡æ˜¯é€šè¿‡å°†å…±äº«ç©ºé—´ç¼“å†²åŒºç›´æŽ¥é™„åŠ åˆ°è¿›ç¨‹çš„è™šæ‹Ÿåœ°å€ç©ºé—´ä¸æ¥å®žçŽ°çš„ï¼Œå› æ¤è¿›ç¨‹é—´çš„读写æ“ä½œçš„åŒæ¥é—®é¢˜
- 利用内å˜ç¼“冲区直接交æ¢ä¿¡æ¯ï¼Œå†…å˜çš„实体å˜åœ¨äºŽè®¡ç®—机ä¸ï¼Œåªèƒ½åŒä¸€ä¸ªè®¡ç®—机系统ä¸çš„è¯¸å¤šè¿›ç¨‹å…±äº«ï¼Œä¸æ–¹ä¾¿ç½‘络通信
- 套接å—(Socket):å¯ç”¨äºŽä¸åŒè®¡ç®—机间的进程通信
- 优点:
- ä¼ è¾“æ•°æ®ä¸ºå—èŠ‚çº§ï¼Œä¼ è¾“æ•°æ®å¯è‡ªå®šä¹‰ï¼Œæ•°æ®é‡å°æ•ˆçŽ‡é«˜
- ä¼ è¾“æ•°æ®æ—¶é—´çŸï¼Œæ€§èƒ½é«˜
- 适åˆäºŽå®¢æˆ·ç«¯å’ŒæœåŠ¡å™¨ç«¯ä¹‹é—´ä¿¡æ¯å®žæ—¶äº¤äº’
- å¯ä»¥åР坆,æ•°æ®å®‰å…¨æ€§å¼º
- ç¼ºç‚¹ï¼šéœ€å¯¹ä¼ è¾“çš„æ•°æ®è¿›è¡Œè§£æžï¼Œè½¬åŒ–æˆåº”用级的数æ®ã€‚
- 优点:
- 锿œºåˆ¶ï¼šåŒ…括互斥é”/é‡ï¼ˆmutex)ã€è¯»å†™é”(reader-writer lock)ã€è‡ªæ—‹é”(spin lockï¼‰ã€æ¡ä»¶å˜é‡ï¼ˆcondition)
- 互斥é”/é‡ï¼ˆmutex):æä¾›äº†ä»¥æŽ’ä»–æ–¹å¼é˜²æ¢æ•°æ®ç»“构被并å‘修改的方法。
- 读写é”(reader-writer lock):å…è®¸å¤šä¸ªçº¿ç¨‹åŒæ—¶è¯»å…±äº«æ•°æ®ï¼Œè€Œå¯¹å†™æ“作是互斥的。
- 自旋é”(spin lock)与互斥é”ç±»ä¼¼ï¼Œéƒ½æ˜¯ä¸ºäº†ä¿æŠ¤å…±äº«èµ„æºã€‚äº’æ–¥é”æ˜¯å½“资æºè¢«å 用,申请者进入ç¡çœ 状æ€ï¼›è€Œè‡ªæ—‹é”åˆ™å¾ªçŽ¯æ£€æµ‹ä¿æŒè€…是å¦å·²ç»é‡Šæ”¾é”。
- æ¡ä»¶å˜é‡ï¼ˆcondition):å¯ä»¥ä»¥åŽŸå的方å¼é˜»å¡žè¿›ç¨‹ï¼Œç›´åˆ°æŸä¸ªç‰¹å®šæ¡ä»¶ä¸ºçœŸä¸ºæ¢ã€‚对æ¡ä»¶çš„æµ‹è¯•是在互斥é”çš„ä¿æŠ¤ä¸‹è¿›è¡Œçš„ã€‚æ¡ä»¶å˜é‡å§‹ç»ˆä¸Žäº’æ–¥é”一起使用。
- ä¿¡å·é‡æœºåˆ¶(Semaphore)
- æ— å线程信å·é‡
- 命å线程信å·é‡
- ä¿¡å·æœºåˆ¶(Signal):类似进程间的信å·å¤„ç†
- å±éšœï¼ˆbarrier):å±éšœå…许æ¯ä¸ªçº¿ç¨‹ç‰å¾…,直到所有的åˆä½œçº¿ç¨‹éƒ½è¾¾åˆ°æŸä¸€ç‚¹ï¼Œç„¶åŽä»Žè¯¥ç‚¹ç»§ç»æ‰§è¡Œã€‚
çº¿ç¨‹é—´çš„é€šä¿¡ç›®çš„ä¸»è¦æ˜¯ç”¨äºŽçº¿ç¨‹åŒæ¥ï¼Œæ‰€ä»¥çº¿ç¨‹æ²¡æœ‰åƒè¿›ç¨‹é€šä¿¡ä¸çš„用于数æ®äº¤æ¢çš„通信机制
进程之间的通信方å¼ä»¥åŠä¼˜ç¼ºç‚¹æ¥æºäºŽï¼šè¿›ç¨‹çº¿ç¨‹é¢è¯•题总结
- ç§æœ‰ï¼šåœ°å€ç©ºé—´ã€å †ã€å…¨å±€å˜é‡ã€æ ˆã€å¯„å˜å™¨
- å…±äº«ï¼šä»£ç æ®µï¼Œå…¬å…±æ•°æ®ï¼Œè¿›ç¨‹ç›®å½•,进程 ID
- ç§æœ‰ï¼šçº¿ç¨‹æ ˆï¼Œå¯„å˜å™¨ï¼Œç¨‹åºè®¡æ•°å™¨
- å…±äº«ï¼šå †ï¼Œåœ°å€ç©ºé—´ï¼Œå…¨å±€å˜é‡ï¼Œé™æ€å˜é‡
对比维度 | 多进程 | 多线程 | 总结 |
---|---|---|---|
æ•°æ®å…±äº«ã€åŒæ¥ | æ•°æ®å…±äº«å¤æ‚,需è¦ç”¨ IPCï¼›æ•°æ®æ˜¯åˆ†å¼€çš„ï¼ŒåŒæ¥ç®€å• | å› ä¸ºå…±äº«è¿›ç¨‹æ•°æ®ï¼Œæ•°æ®å…±äº«ç®€å•ï¼Œä½†ä¹Ÿæ˜¯å› ä¸ºè¿™ä¸ªåŽŸå› å¯¼è‡´åŒæ¥å¤æ‚ | 儿œ‰ä¼˜åŠ¿ |
内å˜ã€CPU | å 用内å˜å¤šï¼Œåˆ‡æ¢å¤æ‚,CPU 利用率低 | å 用内å˜å°‘,切æ¢ç®€å•,CPU 利用率高 | 线程å 优 |
创建销æ¯ã€åˆ‡æ¢ | 创建销æ¯ã€åˆ‡æ¢å¤æ‚,速度慢 | 创建销æ¯ã€åˆ‡æ¢ç®€å•,速度很快 | 线程å 优 |
编程ã€è°ƒè¯• | 编程简å•ï¼Œè°ƒè¯•ç®€å• | ç¼–ç¨‹å¤æ‚ï¼Œè°ƒè¯•å¤æ‚ | 进程å 优 |
å¯é 性 | 进程间ä¸ä¼šäº’ç›¸å½±å“ | 一个线程挂掉将导致整个进程挂掉 | 进程å 优 |
åˆ†å¸ƒå¼ | é€‚åº”äºŽå¤šæ ¸ã€å¤šæœºåˆ†å¸ƒå¼ï¼›å¦‚æžœä¸€å°æœºå™¨ä¸å¤Ÿï¼Œæ‰©å±•åˆ°å¤šå°æœºå™¨æ¯”è¾ƒç®€å• | é€‚åº”äºŽå¤šæ ¸åˆ†å¸ƒå¼ | 进程å 优 |
优劣 | 多进程 | 多线程 |
---|---|---|
优点 | 编程ã€è°ƒè¯•简å•,å¯é 性较高 | 创建ã€é”€æ¯ã€åˆ‡æ¢é€Ÿåº¦å¿«ï¼Œå†…å˜ã€èµ„æºå ç”¨å° |
缺点 | 创建ã€é”€æ¯ã€åˆ‡æ¢é€Ÿåº¦æ…¢ï¼Œå†…å˜ã€èµ„æºå 用大 | 编程ã€è°ƒè¯•夿‚,å¯é 性较差 |
- 需è¦é¢‘ç¹åˆ›å»ºé”€æ¯çš„优先用线程
- 需è¦è¿›è¡Œå¤§é‡è®¡ç®—的优先使用线程
- 强相关的处ç†ç”¨çº¿ç¨‹ï¼Œå¼±ç›¸å…³çš„处ç†ç”¨è¿›ç¨‹
- å¯èƒ½è¦æ‰©å±•åˆ°å¤šæœºåˆ†å¸ƒçš„ç”¨è¿›ç¨‹ï¼Œå¤šæ ¸åˆ†å¸ƒçš„ç”¨çº¿ç¨‹
- éƒ½æ»¡è¶³éœ€æ±‚çš„æƒ…å†µä¸‹ï¼Œç”¨ä½ æœ€ç†Ÿæ‚‰ã€æœ€æ‹¿æ‰‹çš„æ–¹å¼
多进程与多线程间的对比ã€ä¼˜åŠ£ä¸Žé€‰æ‹©æ¥è‡ªï¼šå¤šçº¿ç¨‹è¿˜æ˜¯å¤šè¿›ç¨‹çš„选择åŠåŒºåˆ«
在现代æ“作系统里,åŒä¸€æ—¶é—´å¯èƒ½æœ‰å¤šä¸ªå†…æ ¸æ‰§è¡Œæµåœ¨æ‰§è¡Œï¼Œå› æ¤å†…æ ¸å…¶å®žåƒå¤šè¿›ç¨‹å¤šçº¿ç¨‹ç¼–ç¨‹ä¸€æ ·ä¹Ÿéœ€è¦ä¸€äº›åŒæ¥æœºåˆ¶æ¥åŒæ¥å„执行å•元对共享数æ®çš„访问。尤其是在多处ç†å™¨ç³»ç»Ÿä¸Šï¼Œæ›´éœ€è¦ä¸€äº›åŒæ¥æœºåˆ¶æ¥åŒæ¥ä¸åŒå¤„ç†å™¨ä¸Šçš„æ‰§è¡Œå•元对共享的数æ®çš„访问。
- åŽŸåæ“ä½œ
- ä¿¡å·é‡ï¼ˆsemaphore)
- 读写信å·é‡ï¼ˆrw_semaphore)
- 自旋é”(spinlock)
- å¤§å†…æ ¸é”(BKL,Big Kernel Lock)
- 读写é”(rwlock)
- 大读者é”(brlock-Big Reader Lock)
- 读-æ‹·è´ä¿®æ”¹(RCU,Read-Copy Update)
- 顺åºé”(seqlock)
æ¥è‡ªï¼šLinux å†…æ ¸çš„åŒæ¥æœºåˆ¶ï¼Œç¬¬ 1 部分ã€Linux å†…æ ¸çš„åŒæ¥æœºåˆ¶ï¼Œç¬¬ 2 部分
- 系统资æºä¸è¶³
- 资æºåˆ†é…ä¸å½“
- 进程è¿è¡ŒæŽ¨è¿›é¡ºåºä¸åˆé€‚
- 互斥
- è¯·æ±‚å’Œä¿æŒ
- ä¸å‰¥å¤º
- 环路
- æ‰“ç ´äº’æ–¥æ¡ä»¶ï¼šæ”¹é€ ç‹¬å æ€§èµ„æºä¸ºè™šæ‹Ÿèµ„æºï¼Œå¤§éƒ¨åˆ†èµ„æºå·²æ— æ³•æ”¹é€ ã€‚
- æ‰“ç ´ä¸å¯æŠ¢å æ¡ä»¶ï¼šå½“ä¸€è¿›ç¨‹å æœ‰ä¸€ç‹¬å 性资æºåŽåˆç”³è¯·ä¸€ç‹¬å 性资æºè€Œæ— æ³•æ»¡è¶³ï¼Œåˆ™é€€å‡ºåŽŸå æœ‰çš„资æºã€‚
- æ‰“ç ´å æœ‰ä¸”申请æ¡ä»¶ï¼šé‡‡ç”¨èµ„æºé¢„先分é…ç–略,å³è¿›ç¨‹è¿è¡Œå‰ç”³è¯·å…¨éƒ¨èµ„æºï¼Œæ»¡è¶³åˆ™è¿è¡Œï¼Œä¸ç„¶å°±ç‰å¾…ï¼Œè¿™æ ·å°±ä¸ä¼šå 有且申请。
- æ‰“ç ´å¾ªçŽ¯ç‰å¾…æ¡ä»¶ï¼šå®žçŽ°èµ„æºæœ‰åºåˆ†é…ç–略,对所有设备实现分类编å·ï¼Œæ‰€æœ‰è¿›ç¨‹åªèƒ½é‡‡ç”¨æŒ‰åºå·é€’增的形å¼ç”³è¯·èµ„æºã€‚
- 有åºèµ„æºåˆ†é…法
- 银行家算法
- Windows:FCB 表 + FAT + ä½å›¾
- Unix:inode + æ··åˆç´¢å¼• + æˆç»„链接
主机å—节åºåˆå« CPU å—节åºï¼Œå…¶ä¸æ˜¯ç”±æ“作系统决定的,而是由 CPU 指令集架构决定的。主机å—节åºåˆ†ä¸ºä¸¤ç§ï¼š
- 大端å—节åºï¼ˆBig Endian):高åºå—节å˜å‚¨åœ¨ä½Žä½åœ°å€ï¼Œä½Žåºå—节å˜å‚¨åœ¨é«˜ä½åœ°å€
- å°ç«¯å—节åºï¼ˆLittle Endian):高åºå—节å˜å‚¨åœ¨é«˜ä½åœ°å€ï¼Œä½Žåºå—节å˜å‚¨åœ¨ä½Žä½åœ°å€
32 使•´æ•° 0x12345678
是从起始ä½ç½®ä¸º 0x00
的地å€å¼€å§‹å˜æ”¾ï¼Œåˆ™ï¼š
内å˜åœ°å€ | 0x00 | 0x01 | 0x02 | 0x03 |
---|---|---|---|---|
大端 | 12 | 34 | 56 | 78 |
å°ç«¯ | 78 | 56 | 34 | 12 |
大端å°ç«¯å›¾ç‰‡
判æ–大端å°ç«¯
å¯ä»¥è¿™æ ·åˆ¤æ–自己 CPU å—èŠ‚åºæ˜¯å¤§ç«¯è¿˜æ˜¯å°ç«¯ï¼š
#include <iostream>
using namespace std;
int main()
{
int i = 0x12345678;
if (*((char*)&i) == 0x12)
cout << "大端" << endl;
else
cout << "å°ç«¯" << endl;
return 0;
}
- x86(Intelã€AMD)ã€MOS Technology 6502ã€Z80ã€VAXã€PDP-11 ç‰å¤„ç†å™¨ä¸ºå°ç«¯åºï¼›
- Motorola 6800ã€Motorola 68000ã€PowerPC 970ã€System/370ã€SPARC(除 V9 外)ç‰å¤„ç†å™¨ä¸ºå¤§ç«¯åºï¼›
- ARM(默认å°ç«¯åºï¼‰ã€PowerPC(除 PowerPC 970 外)ã€DEC Alphaã€SPARC V9ã€MIPSã€PA-RISC åŠ IA64 çš„å—èŠ‚åºæ˜¯å¯é…置的。
网络å—èŠ‚é¡ºåºæ˜¯ TCP/IP ä¸è§„å®šå¥½çš„ä¸€ç§æ•°æ®è¡¨ç¤ºæ ¼å¼ï¼Œå®ƒä¸Žå…·ä½“çš„ CPU ç±»åž‹ã€æ“ä½œç³»ç»Ÿç‰æ— 关,从而å¯ä»¥ä¿è¯æ•°æ®åœ¨ä¸åŒä¸»æœºä¹‹é—´ä¼ 输时能够被æ£ç¡®è§£é‡Šã€‚
网络å—节顺åºé‡‡ç”¨ï¼šå¤§ç«¯ï¼ˆBig Endian)排列方å¼ã€‚
åœ¨åœ°å€æ˜ 射过程ä¸ï¼Œè‹¥åœ¨é¡µé¢ä¸å‘现所è¦è®¿é—®çš„页é¢ä¸åœ¨å†…å˜ä¸ï¼Œåˆ™äº§ç”Ÿç¼ºé¡µä¸æ–。当å‘ç”Ÿç¼ºé¡µä¸æ–时,如果æ“作系统内å˜ä¸æ²¡æœ‰ç©ºé—²é¡µé¢ï¼Œåˆ™æ“作系统必须在内å˜é€‰æ‹©ä¸€ä¸ªé¡µé¢å°†å…¶ç§»å‡ºå†…å˜ï¼Œä»¥ä¾¿ä¸ºå³å°†è°ƒå…¥çš„页é¢è®©å‡ºç©ºé—´ã€‚而用æ¥é€‰æ‹©æ·˜æ±°å“ªä¸€é¡µçš„规则å«åšé¡µé¢ç½®æ¢ç®—法。
- 全局置æ¢ï¼šåœ¨æ•´ä¸ªå†…å˜ç©ºé—´ç½®æ¢
- 局部置æ¢ï¼šåœ¨æœ¬è¿›ç¨‹ä¸è¿›è¡Œç½®æ¢
全局:
- 工作集算法
- 缺页率置æ¢ç®—法
局部:
- 最佳置æ¢ç®—法(OPT)
- 先进先出置æ¢ç®—法(FIFO)
- 最近最久未使用(LRU)算法
- 时钟(Clock)置æ¢ç®—法
本节部分知识点æ¥è‡ªã€Šè®¡ç®—机网络(第 7 版)》
计算机网络体系结构:
分层 | 作用 | åè®® |
---|---|---|
物ç†å±‚ | é€šè¿‡åª’ä»‹ä¼ è¾“æ¯”ç‰¹ï¼Œç¡®å®šæœºæ¢°åŠç”µæ°”规范(比特 Bit) | RJ45ã€CLOCKã€IEEE802.3(ä¸ç»§å™¨ï¼Œé›†çº¿å™¨ï¼‰ |
æ•°æ®é“¾è·¯å±‚ | 将比特组装æˆå¸§å’Œç‚¹åˆ°ç‚¹çš„ä¼ é€’ï¼ˆå¸§ Frame) | PPPã€FRã€HDLCã€VLANã€MACï¼ˆç½‘æ¡¥ï¼Œäº¤æ¢æœºï¼‰ |
网络层 | 负责数æ®åŒ…从æºåˆ°å®¿çš„ä¼ é€’å’Œç½‘é™…äº’è¿žï¼ˆåŒ… Packet) | IPã€ICMPã€ARPã€RARPã€OSPFã€IPXã€RIPã€IGRP(路由器) |
è¿è¾“层 | æä¾›ç«¯åˆ°ç«¯çš„å¯é æŠ¥æ–‡ä¼ é€’å’Œé”™è¯¯æ¢å¤ï¼ˆ 段Segment) | TCPã€UDPã€SPX |
会è¯å±‚ | 建立ã€ç®¡ç†å’Œç»ˆæ¢ä¼šè¯ï¼ˆä¼šè¯å议数æ®å•å…ƒ SPDU) | NFSã€SQLã€NETBIOSã€RPC |
表示层 | 对数æ®è¿›è¡Œç¿»è¯‘ã€åŠ å¯†å’ŒåŽ‹ç¼©ï¼ˆè¡¨ç¤ºå议数æ®å•å…ƒ PPDU) | JPEGã€MPEGã€ASII |
应用层 | å…许访问OSI环境的手段(应用å议数æ®å•å…ƒ APDU) | FTPã€DNSã€Telnetã€SMTPã€HTTPã€WWWã€NFS |
- ä¼ è¾“æ•°æ®çš„å•ä½ï¼šæ¯”特
- æ•°æ®ä¼ 输系统:æºç³»ç»Ÿï¼ˆæºç‚¹ã€å‘é€å™¨ï¼‰ --> ä¼ è¾“ç³»ç»Ÿ --> 目的系统(接收器ã€ç»ˆç‚¹ï¼‰
通é“:
- å•å‘通é“(å•工通é“ï¼‰ï¼šåªæœ‰ä¸€ä¸ªæ–¹å‘é€šä¿¡ï¼Œæ²¡æœ‰åæ–¹å‘交互,如广æ’
- åŒå‘交替通信(åŠåŒå·¥é€šä¿¡ï¼‰ï¼šé€šä¿¡åŒæ–¹éƒ½å¯å‘消æ¯ï¼Œä½†ä¸èƒ½åŒæ—¶å‘逿ˆ–接收
- åŒå‘åŒæ—¶é€šä¿¡ï¼ˆå…¨åŒå·¥é€šä¿¡ï¼‰ï¼šé€šä¿¡åŒæ–¹å¯ä»¥åŒæ—¶å‘é€å’ŒæŽ¥æ”¶ä¿¡æ¯
通é“å¤ç”¨æŠ€æœ¯ï¼š
- 频分å¤ç”¨ï¼ˆFDM,Frequency Division Multiplexing):ä¸åŒç”¨æˆ·åœ¨ä¸åŒé¢‘å¸¦ï¼Œæ‰€ç”¨ç”¨æˆ·åœ¨åŒæ ·æ—¶é—´å 用ä¸åŒå¸¦å®½èµ„æº
- 时分å¤ç”¨ï¼ˆTDM,Time Division Multiplexing):ä¸åŒç”¨æˆ·åœ¨åŒä¸€æ—¶é—´æ®µçš„ä¸åŒæ—¶é—´ç‰‡ï¼Œæ‰€æœ‰ç”¨æˆ·åœ¨ä¸åŒæ—¶é—´å ç”¨åŒæ ·çš„频带宽度
- 波分å¤ç”¨ï¼ˆWDM,Wavelength Division Multiplexing):光的频分å¤ç”¨
- ç 分å¤ç”¨ï¼ˆCDM,Code Division Multiplexing):ä¸åŒç”¨æˆ·ä½¿ç”¨ä¸åŒçš„ç ,å¯ä»¥åœ¨åŒæ ·æ—¶é—´ä½¿ç”¨åŒæ ·é¢‘带通信
主è¦ä¿¡é“:
- 点对点信é“
- 广æ’ä¿¡é“
- æ•°æ®å•元:帧
三个基本问题:
- å°è£…æˆå¸§ï¼šæŠŠç½‘络层的 IP æ•°æ®æŠ¥å°è£…æˆå¸§ï¼Œ
SOH - æ•°æ®éƒ¨åˆ† - EOT
- 逿˜Žä¼ 输:ä¸ç®¡æ•°æ®éƒ¨åˆ†ä»€ä¹ˆå—ç¬¦ï¼Œéƒ½èƒ½ä¼ è¾“å‡ºåŽ»ï¼›å¯ä»¥é€šè¿‡å—节填充方法解决(冲çªå—符å‰åŠ è½¬ä¹‰å—符)
- 差错检测:é™ä½Žè¯¯ç 率(BER,Bit Error Rate),广泛使用循环冗余检测(CRC,Cyclic Redundancy Check)
点对点å议(Point-to-Point Protocol):
- 点对点å议(Point-to-Point Protocol):用户计算机和 ISP 通信时所使用的åè®®
广æ’通信:
- 硬件地å€ï¼ˆç‰©ç†åœ°å€ã€MAC 地å€ï¼‰
- 啿’(unicast)帧(一对一):收到的帧的 MAC 地å€ä¸Žæœ¬ç«™çš„硬件地å€ç›¸åŒ
- 广æ’(broadcast)帧(一对全体):å‘é€ç»™æœ¬å±€åŸŸç½‘上所有站点的帧
- 多æ’(multicast)帧(一对多):å‘é€ç»™æœ¬å±€åŸŸç½‘上一部分站点的帧
- IP(Internet Protocol,网际å议)是为计算机网络相互连接进行通信而设计的å议。
- ARP(Address Resolution Protocol,地å€è§£æžå议)
- ICMP(Internet Control Message Protocol,网际控制报文å议)
- IGMP(Internet Group Management Protocol,网际组管ç†å议)
IP 地å€åˆ†ç±»ï¼š
IP åœ°å€ ::= {<网络å·>,<主机å·>}
IP 地å€ç±»åˆ« | ç½‘ç»œå· | 网络范围 | ä¸»æœºå· | IP 地å€èŒƒå›´ |
---|---|---|---|---|
A ç±» | 8bit,第一ä½å›ºå®šä¸º 0 | 0 —— 127 | 24bit | 1.0.0.0 —— 127.255.255.255 |
B ç±» | 16bit,å‰ä¸¤ä½å›ºå®šä¸º 10 | 128.0 —— 191.255 | 16bit | 128.0.0.0 —— 191.255.255.255 |
C ç±» | 24bit,å‰ä¸‰ä½å›ºå®šä¸º 110 | 192.0.0 —— 223.255.255 | 8bit | 192.0.0.0 —— 223.255.255.255 |
D ç±» | å‰å››ä½å›ºå®šä¸º 1110,åŽé¢ä¸ºå¤šæ’åœ°å€ | |||
E ç±» | å‰äº”ä½å›ºå®šä¸º 11110,åŽé¢ä¿ç•™ä¸ºä»ŠåŽæ‰€ç”¨ |
IP æ•°æ®æŠ¥æ ¼å¼ï¼š
ICMP æŠ¥æ–‡æ ¼å¼ï¼š
应用:
- PING(Packet InterNet Groper,分组网间探测)测试两个主机之间的连通性
- TTL(Time To Liveï¼Œç”Ÿå˜æ—¶é—´ï¼‰è¯¥å—段指定 IP 包被路由器丢弃之å‰å…许通过的最大网段数é‡
- RIP(Routing Information Protocol,路由信æ¯å议)
- OSPF(Open Sortest Path First,开放最çŸè·¯å¾„优先)
- BGP(Border Gateway Protocol,边界网关å议)
- IGMP(Internet Group Management Protocol,网际组管ç†å议)
- 多æ’路由选择åè®®
- VPN(Virtual Private Network,虚拟专用网)
- NAT(Network Address Translation,网络地å€è½¬æ¢ï¼‰
- 网络 ID(Network ID, Network numberï¼‰ï¼šå°±æ˜¯ç›®æ ‡åœ°å€çš„网络 ID。
- å网掩ç (subnet mask):用æ¥åˆ¤æ– IP 所属网络
- 下一跳地å€/接å£ï¼ˆNext hop / interface):就是数æ®åœ¨å‘é€åˆ°ç›®æ ‡åœ°å€çš„æ—…途ä¸ä¸‹ä¸€ç«™çš„地å€ã€‚å…¶ä¸ interface æŒ‡å‘ next hop(å³ä¸ºä¸‹ä¸€ä¸ª route)。一个自治系统(AS, Autonomous system)ä¸çš„ route 应该包å«åŒºåŸŸå†…所有的å网络,而默认网关(Network id:
0.0.0.0
, Netmask:0.0.0.0
)指å‘自治系统的出å£ã€‚
æ ¹æ®åº”用和执行的ä¸åŒï¼Œè·¯ç”±è¡¨å¯èƒ½å«æœ‰å¦‚ä¸‹é™„åŠ ä¿¡æ¯ï¼š
- 花费(Cost):就是数æ®å‘é€è¿‡ç¨‹ä¸é€šè¿‡è·¯å¾„所需è¦çš„花费。
- 路由的æœåŠ¡è´¨é‡
- 路由ä¸éœ€è¦è¿‡æ»¤çš„出/入连接列表
å议:
- TCP(Transmission Control Protocolï¼Œä¼ è¾“æŽ§åˆ¶å议)
- UDP(User Datagram Protocolï¼Œç”¨æˆ·æ•°æ®æŠ¥å议)
端å£ï¼š
åº”ç”¨ç¨‹åº | FTP | TELNET | SMTP | DNS | TFTP | HTTP | HTTPS | SNMP |
---|---|---|---|---|---|---|---|---|
端å£å· | 21 | 23 | 25 | 53 | 69 | 80 | 443 | 161 |
- TCP(Transmission Control Protocolï¼Œä¼ è¾“æŽ§åˆ¶å议)是一ç§é¢å‘连接的ã€å¯é çš„ã€åŸºäºŽå—节æµçš„ä¼ è¾“å±‚é€šä¿¡åè®®ï¼Œå…¶ä¼ è¾“çš„å•使˜¯æŠ¥æ–‡æ®µã€‚
特å¾ï¼š
- é¢å‘连接
- åªèƒ½ç‚¹å¯¹ç‚¹ï¼ˆä¸€å¯¹ä¸€ï¼‰é€šä¿¡
- å¯é 交互
- å…¨åŒå·¥é€šä¿¡
- é¢å‘å—节æµ
TCP 如何ä¿è¯å¯é ä¼ è¾“ï¼š
- 确认和超时é‡ä¼
- æ•°æ®åˆç†åˆ†ç‰‡å’ŒæŽ’åº
- æµé‡æŽ§åˆ¶
- 拥塞控制
- æ•°æ®æ ¡éªŒ
TCP 报文结构
TCP 首部
TCPï¼šçŠ¶æ€æŽ§åˆ¶ç (Code,Control Flag),å 6 比特,å«ä¹‰å¦‚下:
- URG:紧急比特(urgent),当
URGï¼1
æ—¶ï¼Œè¡¨æ˜Žç´§æ€¥æŒ‡é’ˆå—æ®µæœ‰æ•ˆï¼Œä»£è¡¨è¯¥å°åŒ…为紧急å°åŒ…ã€‚å®ƒå‘Šè¯‰ç³»ç»Ÿæ¤æŠ¥æ–‡æ®µä¸æœ‰ç´§æ€¥æ•°æ®ï¼Œåº”å°½å¿«ä¼ é€(相当于高优先级的数æ®), 且上图ä¸çš„ Urgent Pointer å—æ®µä¹Ÿä¼šè¢«å¯ç”¨ã€‚ - ACK:确认比特(Acknowledgeï¼‰ã€‚åªæœ‰å½“
ACKï¼1
时确认å·å—æ®µæ‰æœ‰æ•ˆï¼Œä»£è¡¨è¿™ä¸ªå°åŒ…为确认å°åŒ…。当ACKï¼0
æ—¶ï¼Œç¡®è®¤å·æ— 效。 - PSH:(Push function)若为 1 æ—¶ï¼Œä»£è¡¨è¦æ±‚对方立å³ä¼ é€ç¼“冲区内的其他对应å°åŒ…ï¼Œè€Œæ— éœ€ç‰ç¼“冲满了æ‰é€ã€‚
- RST:å¤ä½æ¯”特(Reset),当
RSTï¼1
时,表明 TCP 连接ä¸å‡ºçް䏥é‡å·®é”™ï¼ˆå¦‚ç”±äºŽä¸»æœºå´©æºƒæˆ–å…¶ä»–åŽŸå› ï¼‰ï¼Œå¿…é¡»é‡Šæ”¾è¿žæŽ¥ï¼Œç„¶åŽå†é‡æ–°å»ºç«‹è¿è¾“连接。 - SYNï¼šåŒæ¥æ¯”特(Synchronous),SYN 置为 1ï¼Œå°±è¡¨ç¤ºè¿™æ˜¯ä¸€ä¸ªè¿žæŽ¥è¯·æ±‚æˆ–è¿žæŽ¥æŽ¥å—æŠ¥æ–‡ï¼Œé€šå¸¸å¸¦æœ‰ SYN æ ‡å¿—çš„å°åŒ…表示『主动ã€è¦è¿žæŽ¥åˆ°å¯¹æ–¹çš„æ„æ€ã€‚
- FINï¼šç»ˆæ¢æ¯”特(Final),用æ¥é‡Šæ”¾ä¸€ä¸ªè¿žæŽ¥ã€‚当
FINï¼1
æ—¶ï¼Œè¡¨æ˜Žæ¤æŠ¥æ–‡æ®µçš„å‘é€ç«¯çš„æ•°æ®å·²å‘é€å®Œæ¯•ï¼Œå¹¶è¦æ±‚释放è¿è¾“连接。
- UDP(User Datagram Protocolï¼Œç”¨æˆ·æ•°æ®æŠ¥å议)是 OSI(Open System Interconnection 开放å¼ç³»ç»Ÿäº’è”) å‚考模型ä¸ä¸€ç§æ— è¿žæŽ¥çš„ä¼ è¾“å±‚å议,æä¾›é¢å‘事务的简å•ä¸å¯é ä¿¡æ¯ä¼ 逿œåŠ¡ï¼Œå…¶ä¼ è¾“çš„å•使˜¯ç”¨æˆ·æ•°æ®æŠ¥ã€‚
特å¾ï¼š
- æ— è¿žæŽ¥
- 尽最大努力交付
- é¢å‘报文
- 没有拥塞控制
- 支æŒä¸€å¯¹ä¸€ã€ä¸€å¯¹å¤šã€å¤šå¯¹ä¸€ã€å¤šå¯¹å¤šçš„交互通信
- 首部开销å°
UDP 报文结构
UDP 首部
TCP/UDP å›¾ç‰‡æ¥æºäºŽï¼šhttps://github.com/JerryC8080/understand-tcp-udp
- TCP é¢å‘连接,UDP æ˜¯æ— è¿žæŽ¥çš„ï¼›
- TCP æä¾›å¯é çš„æœåŠ¡ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œé€šè¿‡ TCP è¿žæŽ¥ä¼ é€çš„æ•°æ®ï¼Œæ— 差错,ä¸ä¸¢å¤±ï¼Œä¸é‡å¤ï¼Œä¸”按åºåˆ°è¾¾ï¼›UDP 尽最大努力交付,å³ä¸ä¿è¯å¯é 交付
- TCP çš„é€»è¾‘é€šä¿¡ä¿¡é“æ˜¯å…¨åŒå·¥çš„å¯é ä¿¡é“ï¼›UDP 则是ä¸å¯é ä¿¡é“
- æ¯ä¸€æ¡ TCP 连接åªèƒ½æ˜¯ç‚¹åˆ°ç‚¹çš„ï¼›UDP 支æŒä¸€å¯¹ä¸€ï¼Œä¸€å¯¹å¤šï¼Œå¤šå¯¹ä¸€å’Œå¤šå¯¹å¤šçš„交互通信
- TCP é¢å‘å—节æµï¼ˆå¯èƒ½å‡ºçްé»åŒ…问题),实际上是 TCP 把数æ®çœ‹æˆä¸€è¿žä¸²æ— 结构的å—节æµï¼›UDP 是é¢å‘报文的(ä¸ä¼šå‡ºçްé»åŒ…问题)
- UDP æ²¡æœ‰æ‹¥å¡žæŽ§åˆ¶ï¼Œå› æ¤ç½‘络出现拥塞ä¸ä¼šä½¿æºä¸»æœºçš„å‘é€é€Ÿçއé™ä½Žï¼ˆå¯¹å®žæ—¶åº”用很有用,如 IP 电è¯ï¼Œå®žæ—¶è§†é¢‘会议ç‰ï¼‰
- TCP 首部开销20å—节;UDP 的首部开销å°ï¼Œåªæœ‰ 8 个å—节
TCP 是一个基于å—节æµçš„ä¼ è¾“æœåŠ¡ï¼ˆUDP 基于报文的),“æµâ€ æ„å‘³ç€ TCP æ‰€ä¼ è¾“çš„æ•°æ®æ˜¯æ²¡æœ‰è¾¹ç•Œçš„。所以å¯èƒ½ä¼šå‡ºçŽ°ä¸¤ä¸ªæ•°æ®åŒ…é»åœ¨ä¸€èµ·çš„æƒ…况。
- å‘é€å®šé•¿åŒ…。如果æ¯ä¸ªæ¶ˆæ¯çš„大å°éƒ½æ˜¯ä¸€æ ·çš„ï¼Œé‚£ä¹ˆåœ¨æŽ¥æ”¶å¯¹ç‰æ–¹åªè¦ç´¯è®¡æŽ¥æ”¶æ•°æ®ï¼Œç›´åˆ°æ•°æ®ç‰äºŽä¸€ä¸ªå®šé•¿çš„æ•°å€¼å°±å°†å®ƒä½œä¸ºä¸€ä¸ªæ¶ˆæ¯ã€‚
- åŒ…å¤´åŠ ä¸ŠåŒ…ä½“é•¿åº¦ã€‚åŒ…å¤´æ˜¯å®šé•¿çš„ 4 个å—èŠ‚ï¼Œè¯´æ˜Žäº†åŒ…ä½“çš„é•¿åº¦ã€‚æŽ¥æ”¶å¯¹ç‰æ–¹å…ˆæŽ¥æ”¶åŒ…å¤´é•¿åº¦ï¼Œä¾æ®åŒ…å¤´é•¿åº¦æ¥æŽ¥æ”¶åŒ…ä½“ã€‚
- 在数æ®åŒ…ä¹‹é—´è®¾ç½®è¾¹ç•Œï¼Œå¦‚æ·»åŠ ç‰¹æ®Šç¬¦å·
\r\n
æ ‡è®°ã€‚FTP åè®®æ£æ˜¯è¿™ä¹ˆåšçš„ã€‚ä½†é—®é¢˜åœ¨äºŽå¦‚æžœæ•°æ®æ£æ–‡ä¸ä¹Ÿå«æœ‰\r\n
,则会误判为消æ¯çš„边界。 - ä½¿ç”¨æ›´åŠ å¤æ‚的应用层å议。
æµé‡æŽ§åˆ¶ï¼ˆflow control)就是让å‘逿–¹çš„å‘é€é€Ÿçއä¸è¦å¤ªå¿«ï¼Œè¦è®©æŽ¥æ”¶æ–¹æ¥å¾—åŠæŽ¥æ”¶ã€‚
利用å¯å˜çª—å£è¿›è¡Œæµé‡æŽ§åˆ¶
拥塞控制就是防æ¢è¿‡å¤šçš„æ•°æ®æ³¨å…¥åˆ°ç½‘络ä¸ï¼Œè¿™æ ·å¯ä»¥ä½¿ç½‘络ä¸çš„路由器或链路ä¸è‡´è¿‡è½½ã€‚
- 慢开始( slow-start )
- 拥塞é¿å…( congestion avoidance )
- å¿«é‡ä¼ ( fast retransmit )
- å¿«æ¢å¤( fast recovery )
TCP的拥塞控制图
å› ä¸º TCP ä¸‰æ¬¡æ¡æ‰‹å»ºç«‹è¿žæŽ¥ã€å››æ¬¡æŒ¥æ‰‹é‡Šæ”¾è¿žæŽ¥å¾ˆé‡è¦ï¼Œæ‰€ä»¥é™„上《计算机网络(第 7 版)-谢希ä»ã€‹ä¹¦ä¸å¯¹æ¤ç« 的详细æè¿°ï¼šhttps://gitee.com/huihut/interview/raw/master/images/TCP-transport-connection-management.png
ã€TCP 建立连接全过程解释】
- 客户端å‘é€ SYN ç»™æœåŠ¡å™¨ï¼Œè¯´æ˜Žå®¢æˆ·ç«¯è¯·æ±‚å»ºç«‹è¿žæŽ¥ï¼›
- æœåŠ¡ç«¯æ”¶åˆ°å®¢æˆ·ç«¯å‘çš„ SYNï¼Œå¹¶å›žå¤ SYN+ACK ç»™å®¢æˆ·ç«¯ï¼ˆåŒæ„建立连接);
- 客户端收到æœåŠ¡ç«¯çš„ SYN+ACK åŽï¼Œå›žå¤ ACK ç»™æœåŠ¡ç«¯ï¼ˆè¡¨ç¤ºå®¢æˆ·ç«¯æ”¶åˆ°äº†æœåŠ¡ç«¯å‘çš„åŒæ„报文);
- æœåŠ¡ç«¯æ”¶åˆ°å®¢æˆ·ç«¯çš„ ACK,连接已建立,å¯ä»¥æ•°æ®ä¼ 输。
ã€ç”æ¡ˆä¸€ã€‘å› ä¸ºä¿¡é“ä¸å¯é ,而 TCP 想在ä¸å¯é ä¿¡é“上建立å¯é åœ°ä¼ è¾“ï¼Œé‚£ä¹ˆä¸‰æ¬¡é€šä¿¡æ˜¯ç†è®ºä¸Šçš„æœ€å°å€¼ã€‚(而 UDP 则ä¸éœ€å»ºç«‹å¯é ä¼ è¾“ï¼Œå› æ¤ UDP ä¸éœ€è¦ä¸‰æ¬¡æ¡æ‰‹ã€‚)
Google Groups . TCP å»ºç«‹è¿žæŽ¥ä¸ºä»€ä¹ˆæ˜¯ä¸‰æ¬¡æ¡æ‰‹ï¼Ÿ{技术}{网络通信}
ã€ç”æ¡ˆäºŒã€‘å› ä¸ºåŒæ–¹éƒ½éœ€è¦ç¡®è®¤å¯¹æ–¹æ”¶åˆ°äº†è‡ªå·±å‘é€çš„åºåˆ—å·ï¼Œç¡®è®¤è¿‡ç¨‹æœ€å°‘è¦è¿›è¡Œä¸‰æ¬¡é€šä¿¡ã€‚
知乎 . TCP ä¸ºä»€ä¹ˆæ˜¯ä¸‰æ¬¡æ¡æ‰‹ï¼Œè€Œä¸æ˜¯ä¸¤æ¬¡æˆ–四次?
ã€ç”案三】为了防æ¢å·²å¤±æ•ˆçš„连接请求报文段çªç„¶åˆä¼ é€åˆ°äº†æœåŠ¡ç«¯ï¼Œå› è€Œäº§ç”Ÿé”™è¯¯ã€‚
ã€TCP 释放连接全过程解释】
- 客户端å‘é€ FIN ç»™æœåŠ¡å™¨ï¼Œè¯´æ˜Žå®¢æˆ·ç«¯ä¸å¿…å‘逿•°æ®ç»™æœåŠ¡å™¨äº†ï¼ˆè¯·æ±‚é‡Šæ”¾ä»Žå®¢æˆ·ç«¯åˆ°æœåŠ¡å™¨çš„è¿žæŽ¥ï¼‰ï¼›
- æœåŠ¡å™¨æŽ¥æ”¶åˆ°å®¢æˆ·ç«¯å‘çš„ FINï¼Œå¹¶å›žå¤ ACK ç»™å®¢æˆ·ç«¯ï¼ˆåŒæ„释放从客户端到æœåŠ¡å™¨çš„è¿žæŽ¥ï¼‰ï¼›
- 客户端收到æœåŠ¡ç«¯å›žå¤çš„ ACKï¼Œæ¤æ—¶ä»Žå®¢æˆ·ç«¯åˆ°æœåŠ¡å™¨çš„è¿žæŽ¥å·²é‡Šæ”¾ï¼ˆä½†æœåŠ¡ç«¯åˆ°å®¢æˆ·ç«¯çš„è¿žæŽ¥è¿˜æœªé‡Šæ”¾ï¼Œå¹¶ä¸”å®¢æˆ·ç«¯è¿˜å¯ä»¥æŽ¥æ”¶æ•°æ®ï¼‰ï¼›
- æœåŠ¡ç«¯ç»§ç»å‘é€ä¹‹å‰æ²¡å‘完的数æ®ç»™å®¢æˆ·ç«¯ï¼›
- æœåŠ¡ç«¯å‘é€ FIN+ACK 给客户端,说明æœåŠ¡ç«¯å‘é€å®Œäº†æ•°æ®ï¼ˆè¯·æ±‚释放从æœåŠ¡ç«¯åˆ°å®¢æˆ·ç«¯çš„è¿žæŽ¥ï¼Œå°±ç®—æ²¡æ”¶åˆ°å®¢æˆ·ç«¯çš„å›žå¤ï¼Œè¿‡æ®µæ—¶é—´ä¹Ÿä¼šè‡ªåŠ¨é‡Šæ”¾ï¼‰ï¼›
- 客户端收到æœåŠ¡ç«¯çš„ FIN+ACKï¼Œå¹¶å›žå¤ ACK ç»™æœåŠ¡ç«¯ï¼ˆåŒæ„释放从æœåŠ¡ç«¯åˆ°å®¢æˆ·ç«¯çš„è¿žæŽ¥ï¼‰ï¼›
- æœåŠ¡ç«¯æ”¶åˆ°å®¢æˆ·ç«¯çš„ ACK åŽï¼Œé‡Šæ”¾ä»ŽæœåŠ¡ç«¯åˆ°å®¢æˆ·ç«¯çš„è¿žæŽ¥ã€‚
ã€é—®é¢˜ä¸€ã€‘TCP 为什么è¦è¿›è¡Œå››æ¬¡æŒ¥æ‰‹ï¼Ÿ / 为什么 TCP 建立连接需è¦ä¸‰æ¬¡ï¼Œè€Œé‡Šæ”¾è¿žæŽ¥åˆ™éœ€è¦å››æ¬¡ï¼Ÿ
ã€ç”æ¡ˆä¸€ã€‘å› ä¸º TCP 是全åŒå·¥æ¨¡å¼ï¼Œå®¢æˆ·ç«¯è¯·æ±‚å…³é—连接åŽï¼Œå®¢æˆ·ç«¯å‘æœåŠ¡ç«¯çš„è¿žæŽ¥å…³é—(一二次挥手),æœåŠ¡ç«¯ç»§ç»ä¼ è¾“ä¹‹å‰æ²¡ä¼ 完的数æ®ç»™å®¢æˆ·ç«¯ï¼ˆæ•°æ®ä¼ 输),æœåŠ¡ç«¯å‘客户端的连接关é—(三四次挥手)。所以 TCP 释放连接时æœåŠ¡å™¨çš„ ACK å’Œ FIN 是分开å‘é€çš„(ä¸é—´éš”ç€æ•°æ®ä¼ 输),而 TCP 建立连接时æœåŠ¡å™¨çš„ ACK å’Œ SYN 是一起å‘é€çš„ï¼ˆç¬¬äºŒæ¬¡æ¡æ‰‹ï¼‰ï¼Œæ‰€ä»¥ TCP 建立连接需è¦ä¸‰æ¬¡ï¼Œè€Œé‡Šæ”¾è¿žæŽ¥åˆ™éœ€è¦å››æ¬¡ã€‚
ã€é—®é¢˜äºŒã€‘为什么 TCP 连接时å¯ä»¥ ACK å’Œ SYN 一起å‘é€ï¼Œè€Œé‡Šæ”¾æ—¶åˆ™ ACK å’Œ FIN 分开å‘é€å‘¢ï¼Ÿï¼ˆACK å’Œ FIN 分开是指第二次和第三次挥手)
ã€ç”æ¡ˆäºŒã€‘å› ä¸ºå®¢æˆ·ç«¯è¯·æ±‚é‡Šæ”¾æ—¶ï¼ŒæœåС噍å¯èƒ½è¿˜æœ‰æ•°æ®éœ€è¦ä¼ è¾“ç»™å®¢æˆ·ç«¯ï¼Œå› æ¤æœåŠ¡ç«¯è¦å…ˆå“应客户端 FIN 请求(æœåŠ¡ç«¯å‘é€ ACKï¼‰ï¼Œç„¶åŽæ•°æ®ä¼ è¾“ï¼Œä¼ è¾“å®ŒæˆåŽï¼ŒæœåŠ¡ç«¯å†æå‡º FIN 请求(æœåŠ¡ç«¯å‘é€ FIN);而连接时则没有ä¸é—´çš„æ•°æ®ä¼ è¾“ï¼Œå› æ¤è¿žæŽ¥æ—¶å¯ä»¥ ACK å’Œ SYN 一起å‘é€ã€‚
ã€é—®é¢˜ä¸‰ã€‘为什么客户端释放最åŽéœ€è¦ TIME-WAIT ç‰å¾… 2MSL 呢?
ã€ç”案三】
- 为了ä¿è¯å®¢æˆ·ç«¯å‘é€çš„æœ€åŽä¸€ä¸ª ACK 报文能够到达æœåŠ¡ç«¯ã€‚è‹¥æœªæˆåŠŸåˆ°è¾¾ï¼Œåˆ™æœåŠ¡ç«¯è¶…æ—¶é‡ä¼ FIN+ACK 报文段,客户端å†é‡ä¼ ACKï¼Œå¹¶é‡æ–°è®¡æ—¶ã€‚
- 防æ¢å·²å¤±æ•ˆçš„连接请求报文段出现在本连接ä¸ã€‚TIME-WAIT æŒç» 2MSL å¯ä½¿æœ¬è¿žæŽ¥æŒç»çš„æ—¶é—´å†…æ‰€äº§ç”Ÿçš„æ‰€æœ‰æŠ¥æ–‡æ®µéƒ½ä»Žç½‘ç»œä¸æ¶ˆå¤±ï¼Œè¿™æ ·å¯ä½¿ä¸‹æ¬¡è¿žæŽ¥ä¸ä¸ä¼šå‡ºçŽ°æ—§çš„è¿žæŽ¥æŠ¥æ–‡æ®µã€‚
TCP 有é™çŠ¶æ€æœºå›¾ç‰‡
- DNS(Domain Name System,域å系统)是互è”网的一项æœåŠ¡ã€‚å®ƒä½œä¸ºå°†åŸŸåå’Œ IP 地å€ç›¸äº’æ˜ å°„çš„ä¸€ä¸ªåˆ†å¸ƒå¼æ•°æ®åº“,能够使人更方便地访问互è”网。DNS 使用 TCP å’Œ UDP ç«¯å£ 53。当å‰ï¼Œå¯¹äºŽæ¯ä¸€çº§åŸŸå长度的é™åˆ¶æ˜¯ 63 个å—ç¬¦ï¼ŒåŸŸåæ€»é•¿åº¦åˆ™ä¸èƒ½è¶…过 253 个å—符。
域å:
域å ::= {<三级域å>.<二级域å>.<顶级域å>}
,如:blog.huihut.com
- FTP(File Transfer Protocolï¼Œæ–‡ä»¶ä¼ è¾“åè®®ï¼‰æ˜¯ç”¨äºŽåœ¨ç½‘ç»œä¸Šè¿›è¡Œæ–‡ä»¶ä¼ è¾“çš„ä¸€å¥—æ ‡å‡†å议,使用客户/æœåŠ¡å™¨æ¨¡å¼ï¼Œä½¿ç”¨ TCP æ•°æ®æŠ¥ï¼Œæä¾›äº¤äº’å¼è®¿é—®ï¼ŒåŒå‘ä¼ è¾“ã€‚
- TFTP(Trivial File Transfer Protocolï¼Œç®€å•æ–‡ä»¶ä¼ 输å议)一个å°ä¸”æ˜“å®žçŽ°çš„æ–‡ä»¶ä¼ è¾“å议,也使用客户-æœåŠ¡å™¨æ–¹å¼ï¼Œä½¿ç”¨UDPæ•°æ®æŠ¥ï¼Œåªæ”¯æŒæ–‡ä»¶ä¼ è¾“è€Œä¸æ”¯æŒäº¤äº’,没有列目录,ä¸èƒ½å¯¹ç”¨æˆ·è¿›è¡Œèº«ä»½é‰´å®š
-
TELNET å议是 TCP/IP åè®®æ—ä¸çš„一员,是 Internet 远程登陆æœåŠ¡çš„æ ‡å‡†åè®®å’Œä¸»è¦æ–¹å¼ã€‚它为用户æä¾›äº†åœ¨æœ¬åœ°è®¡ç®—机上完æˆè¿œç¨‹ä¸»æœºå·¥ä½œçš„能力。
-
HTTP(HyperText Transfer Protocolï¼Œè¶…æ–‡æœ¬ä¼ è¾“å议)是用于从 WWW(World Wide Web,万维网)æœåŠ¡å™¨ä¼ è¾“è¶…æ–‡æœ¬åˆ°æœ¬åœ°æµè§ˆå™¨çš„ä¼ é€å议。
-
SMTP(Simple Mail Transfer Protocol,简å•é‚®ä»¶ä¼ è¾“å议)是一组用于由æºåœ°å€åˆ°ç›®çš„地å€ä¼ é€é‚®ä»¶çš„è§„åˆ™ï¼Œç”±å®ƒæ¥æŽ§åˆ¶ä¿¡ä»¶çš„ä¸è½¬æ–¹å¼ã€‚SMTP å议属于 TCP/IP å议簇,它帮助æ¯å°è®¡ç®—机在å‘逿ˆ–ä¸è½¬ä¿¡ä»¶æ—¶æ‰¾åˆ°ä¸‹ä¸€ä¸ªç›®çš„地。
-
Socket 建立网络通信连接至少è¦ä¸€å¯¹ç«¯å£å·ï¼ˆSocket)。Socket 本质是编程接å£ï¼ˆAPI),对 TCP/IP çš„å°è£…,TCP/IP ä¹Ÿè¦æä¾›å¯ä¾›ç¨‹åºå‘˜åšç½‘ç»œå¼€å‘æ‰€ç”¨çš„æŽ¥å£ï¼Œè¿™å°±æ˜¯ Socket 编程接å£ã€‚
- WWW(World Wide Web,环çƒä¿¡æ¯ç½‘,万维网)是一个由许多互相链接的超文本组æˆçš„系统,通过互è”网访问
- URL(Uniform Resource Locator,统一资æºå®šä½ç¬¦ï¼‰æ˜¯å› ç‰¹ç½‘ä¸Šæ ‡å‡†çš„èµ„æºçš„地å€ï¼ˆAddress)
æ ‡å‡†æ ¼å¼ï¼š
å议类型:[//æœåŠ¡å™¨åœ°å€[:端å£å·]][/资æºå±‚级UNIX文件路径]文件å[?查询][#片段ID]
å®Œæ•´æ ¼å¼ï¼š
å议类型:[//[访问资æºéœ€è¦çš„å‡è¯ä¿¡æ¯@]æœåŠ¡å™¨åœ°å€[:端å£å·]][/资æºå±‚级UNIX文件路径]文件å[?查询][#片段ID]
å…¶ä¸ã€è®¿é—®å‡è¯ä¿¡æ¯@ï¼›:端å£å·ï¼›?查询;#片段ID】都属于选填项
如:https://github.com/huihut/interview#cc
HTTP(HyperText Transfer Protocolï¼Œè¶…æ–‡æœ¬ä¼ è¾“å议)是一ç§ç”¨äºŽåˆ†å¸ƒå¼ã€å作å¼å’Œè¶…媒体信æ¯ç³»ç»Ÿçš„应用层å议。HTTP 是万维网的数æ®é€šä¿¡çš„基础。
请求方法
方法 | æ„义 |
---|---|
OPTIONS | 请求一些选项信æ¯ï¼Œå…许客户端查看æœåŠ¡å™¨çš„æ€§èƒ½ |
GET | 请求指定的页é¢ä¿¡æ¯ï¼Œå¹¶è¿”回实体主体 |
HEAD | 类似于 get 请求,åªä¸è¿‡è¿”回的å“åº”ä¸æ²¡æœ‰å…·ä½“çš„å†…å®¹ï¼Œç”¨äºŽèŽ·å–æŠ¥å¤´ |
POST | 呿Œ‡å®šèµ„æºæäº¤æ•°æ®è¿›è¡Œå¤„ç†è¯·æ±‚(例如æäº¤è¡¨å•æˆ–è€…ä¸Šä¼ æ–‡ä»¶ï¼‰ã€‚æ•°æ®è¢«åŒ…å«åœ¨è¯·æ±‚体ä¸ã€‚POST请求å¯èƒ½ä¼šå¯¼è‡´æ–°çš„资æºçš„建立和/或已有资æºçš„修改 |
PUT | ä»Žå®¢æˆ·ç«¯å‘æœåŠ¡å™¨ä¼ é€çš„æ•°æ®å–代指定的文档的内容 |
DELETE | 请求æœåŠ¡å™¨åˆ é™¤æŒ‡å®šçš„é¡µé¢ |
TRACE | 回显æœåŠ¡å™¨æ”¶åˆ°çš„è¯·æ±‚ï¼Œä¸»è¦ç”¨äºŽæµ‹è¯•æˆ–è¯Šæ– |
状æ€ç (Status-Code)
- 1xx:表示通知信æ¯ï¼Œå¦‚请求收到了或æ£åœ¨è¿›è¡Œå¤„ç†
- 100 Continue:继ç»ï¼Œå®¢æˆ·ç«¯åº”ç»§ç»å…¶è¯·æ±‚
- 101 Switching Protocols 切æ¢å议。æœåŠ¡å™¨æ ¹æ®å®¢æˆ·ç«¯çš„请求切æ¢å议。åªèƒ½åˆ‡æ¢åˆ°æ›´é«˜çº§çš„å议,例如,切æ¢åˆ° HTTP 的新版本åè®®
- 2xx:表示æˆåŠŸï¼Œå¦‚æŽ¥æ”¶æˆ–çŸ¥é“了
- 200 OK: 请求æˆåŠŸ
- 3xx:表示é‡å®šå‘,如è¦å®Œæˆè¯·æ±‚还必须采å–进一æ¥çš„行动
- 301 Moved Permanently: 永久移动。请求的资æºå·²è¢«æ°¸ä¹…的移动到新 URL,返回信æ¯ä¼šåŒ…括新的 URL,æµè§ˆå™¨ä¼šè‡ªåŠ¨å®šå‘到新 URL。今åŽä»»ä½•新的请求都应使用新的 URL 代替
- 4xxï¼šè¡¨ç¤ºå®¢æˆ·çš„å·®é”™ï¼Œå¦‚è¯·æ±‚ä¸æœ‰é”™è¯¯çš„è¯æ³•或ä¸èƒ½å®Œæˆ
- 400 Bad Request: å®¢æˆ·ç«¯è¯·æ±‚çš„è¯æ³•错误,æœåŠ¡å™¨æ— æ³•ç†è§£
- 401 Unauthorized: è¯·æ±‚è¦æ±‚用户的身份认è¯
- 403 Forbidden: æœåС噍ç†è§£è¯·æ±‚å®¢æˆ·ç«¯çš„è¯·æ±‚ï¼Œä½†æ˜¯æ‹’ç»æ‰§è¡Œæ¤è¯·æ±‚(æƒé™ä¸å¤Ÿï¼‰
- 404 Not Found: æœåŠ¡å™¨æ— æ³•æ ¹æ®å®¢æˆ·ç«¯çš„请求找到资æºï¼ˆç½‘页)。通过æ¤ä»£ç ,网站设计人员å¯è®¾ç½® â€œæ‚¨æ‰€è¯·æ±‚çš„èµ„æºæ— 法找到†的个性页é¢
- 408 Request Timeout: æœåС噍ç‰å¾…客户端å‘é€çš„请求时间过长,超时
- 5xx:表示æœåŠ¡å™¨çš„å·®é”™ï¼Œå¦‚æœåŠ¡å™¨å¤±æ•ˆæ— æ³•å®Œæˆè¯·æ±‚
- 500 Internal Server Error: æœåŠ¡å™¨å†…éƒ¨é”™è¯¯ï¼Œæ— æ³•å®Œæˆè¯·æ±‚
- 503 Service Unavailable: 由于超载或系统维护,æœåŠ¡å™¨æš‚æ—¶çš„æ— æ³•å¤„ç†å®¢æˆ·ç«¯çš„请求。延时的长度å¯åŒ…å«åœ¨æœåŠ¡å™¨çš„ Retry-After 头信æ¯ä¸
- 504 Gateway Timeout: 充当网关或代ç†çš„æœåŠ¡å™¨ï¼ŒæœªåŠæ—¶ä»Žè¿œç«¯æœåŠ¡å™¨èŽ·å–请求
更多状æ€ç :èœé¸Ÿæ•™ç¨‹ . HTTP状æ€ç
- SMTP(Simple Main Transfer Protocol,简å•é‚®ä»¶ä¼ è¾“å议)是在 Internet ä¼ è¾“ Email çš„æ ‡å‡†ï¼Œæ˜¯ä¸€ä¸ªç›¸å¯¹ç®€å•的基于文本的åè®®ã€‚åœ¨å…¶ä¹‹ä¸ŠæŒ‡å®šäº†ä¸€æ¡æ¶ˆæ¯çš„一个或多个接收者(在大多数情况下被确认是å˜åœ¨çš„ï¼‰ï¼Œç„¶åŽæ¶ˆæ¯æ–‡æœ¬ä¼šè¢«ä¼ 输。å¯ä»¥å¾ˆç®€å•地通过 Telnet ç¨‹åºæ¥æµ‹è¯•一个 SMTP æœåŠ¡å™¨ã€‚SMTP 使用 TCP ç«¯å£ 25。
- DHCP(Dynamic Host Configuration Protocol,动æ€ä¸»æœºè®¾ç½®å议)是一个局域网的网络å议,使用 UDP åè®®å·¥ä½œï¼Œä¸»è¦æœ‰ä¸¤ä¸ªç”¨é€”:
- 用于内部网络或网络æœåŠ¡ä¾›åº”å•†è‡ªåŠ¨åˆ†é… IP 地å€ç»™ç”¨æˆ·
- 用于内部网络管ç†å‘˜ä½œä¸ºå¯¹æ‰€æœ‰ç”µè„‘作ä¸å¤®ç®¡ç†çš„æ‰‹æ®µ
- SNMP(Simple Network Management Protocol,简å•网络管ç†å议)构æˆäº†äº’è”网工程工作å°ç»„(IETF,Internet Engineering Task Force)定义的 Internet åè®®æ—的一部分。该å议能够支æŒç½‘络管ç†ç³»ç»Ÿï¼Œç”¨ä»¥ç›‘æµ‹è¿žæŽ¥åˆ°ç½‘ç»œä¸Šçš„è®¾å¤‡æ˜¯å¦æœ‰ä»»ä½•引起管ç†ä¸Šå…³æ³¨çš„æƒ…况。
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
- read 函数是负责从 fd ä¸è¯»å–内容。
- 当读æˆåŠŸæ—¶ï¼Œread 返回实际所读的å—节数。
- 如果返回的值是 0 表示已ç»è¯»åˆ°æ–‡ä»¶çš„结æŸäº†ï¼Œå°äºŽ 0 表示出现了错误。
- 如果错误为 EINTR è¯´æ˜Žè¯»æ˜¯ç”±ä¸æ–引起的;如果是 ECONNREST 表示网络连接出了问题。
- write 函数将 buf ä¸çš„ nbytes å—节内容写入文件æè¿°ç¬¦ fd。
- æˆåŠŸæ—¶è¿”å›žå†™çš„å—节数。失败时返回 -1,并设置 errno å˜é‡ã€‚
- 在网络程åºä¸ï¼Œå½“我们å‘å¥—æŽ¥å—æ–‡ä»¶æè¿°ç¬¦å†™æ—¶æœ‰ä¿©ç§å¯èƒ½ã€‚
- (1)write 的返回值大于 0,表示写了部分或者是全部的数æ®ã€‚
- (2)返回的值å°äºŽ 0ï¼Œæ¤æ—¶å‡ºçŽ°äº†é”™è¯¯ã€‚
- 如果错误为 EINTR è¡¨ç¤ºåœ¨å†™çš„æ—¶å€™å‡ºçŽ°äº†ä¸æ–错误;如果为 EPIPE 表示网络连接出现了问题(对方已ç»å…³é—了连接)。
æˆ‘ä»¬çŸ¥é“ TCP 建立连接è¦è¿›è¡Œ â€œä¸‰æ¬¡æ¡æ‰‹â€ï¼Œå³äº¤æ¢ä¸‰ä¸ªåˆ†ç»„。大致æµç¨‹å¦‚下:
- å®¢æˆ·ç«¯å‘æœåС噍å‘é€ä¸€ä¸ª SYN J
- æœåС噍å‘客户端å“应一个 SYN K,并对 SYN J 进行确认 ACK J+1
- å®¢æˆ·ç«¯å†æƒ³æœåС噍å‘一个确认 ACK K+1
åªæœ‰å°±å®Œäº†ä¸‰æ¬¡æ¡æ‰‹ï¼Œä½†æ˜¯è¿™ä¸ªä¸‰æ¬¡æ¡æ‰‹å‘生在 Socket çš„é‚£å‡ ä¸ªå‡½æ•°ä¸å‘¢ï¼Ÿè¯·çœ‹ä¸‹å›¾ï¼š
从图ä¸å¯ä»¥çœ‹å‡ºï¼š
- 当客户端调用 connect 时,触å‘äº†è¿žæŽ¥è¯·æ±‚ï¼Œå‘æœåС噍å‘é€äº† SYN J 包,这时 connect 进入阻塞状æ€ï¼›
- æœåŠ¡å™¨ç›‘å¬åˆ°è¿žæŽ¥è¯·æ±‚ï¼Œå³æ”¶åˆ° SYN J 包,调用 accept 函数接收请求å‘客户端å‘é€ SYN K ,ACK J+1,这时 accept 进入阻塞状æ€ï¼›
- 客户端收到æœåŠ¡å™¨çš„ SYN K ,ACK J+1 之åŽï¼Œè¿™æ—¶ connect 返回,并对 SYN K 进行确认;
- æœåŠ¡å™¨æ”¶åˆ° ACK K+1 时,accept 返回,至æ¤ä¸‰æ¬¡æ¡æ‰‹å®Œæ¯•,连接建立。
上é¢ä»‹ç»äº† socket ä¸ TCP çš„ä¸‰æ¬¡æ¡æ‰‹å»ºç«‹è¿‡ç¨‹ï¼ŒåŠå…¶æ¶‰åŠçš„ socket å‡½æ•°ã€‚çŽ°åœ¨æˆ‘ä»¬ä»‹ç» socket ä¸çš„å››æ¬¡æ¡æ‰‹é‡Šæ”¾è¿žæŽ¥çš„过程,请看下图:
图示过程如下:
- æŸä¸ªåº”用进程首先调用 close 主动关é—连接,这时 TCP å‘é€ä¸€ä¸ª FIN Mï¼›
- å¦ä¸€ç«¯æŽ¥æ”¶åˆ° FIN M 之åŽï¼Œæ‰§è¡Œè¢«åЍ关é—,对这个 FIN 进行确认。它的接收也作为文件结æŸç¬¦ä¼ é€’ç»™åº”ç”¨è¿›ç¨‹ï¼Œå› ä¸º FIN 的接收æ„味ç€åº”用进程在相应的连接上å†ä¹ŸæŽ¥æ”¶ä¸åˆ°é¢å¤–æ•°æ®ï¼›
- 一段时间之åŽï¼ŒæŽ¥æ”¶åˆ°æ–‡ä»¶ç»“æŸç¬¦çš„应用进程调用 close å…³é—它的 socket。这导致它的 TCP 也å‘é€ä¸€ä¸ª FIN Nï¼›
- 接收到这个 FIN çš„æºå‘é€ç«¯ TCP 对它进行确认。
è¿™æ ·æ¯ä¸ªæ–¹å‘上都有一个 FIN å’Œ ACK。
本节部分知识点æ¥è‡ªã€Šæ•°æ®åº“系统概论(第 5 版)》
- æ•°æ®ï¼ˆdata):æè¿°äº‹ç‰©çš„符å·è®°å½•称为数æ®ã€‚
- æ•°æ®åº“(DataBase,DB):是长期å˜å‚¨åœ¨è®¡ç®—æœºå†…ã€æœ‰ç»„织的ã€å¯å…±äº«çš„大釿•°æ®çš„集åˆï¼Œå…·æœ‰æ°¸ä¹…å˜å‚¨ã€æœ‰ç»„织ã€å¯å…±äº«ä¸‰ä¸ªåŸºæœ¬ç‰¹ç‚¹ã€‚
- æ•°æ®åº“管ç†ç³»ç»Ÿï¼ˆDataBase Management System,DBMS):是ä½äºŽç”¨æˆ·ä¸Žæ“作系统之间的一层数æ®ç®¡ç†è½¯ä»¶ã€‚
- æ•°æ®åº“系统(DataBase System,DBS):是有数æ®åº“ã€æ•°æ®åº“管ç†ç³»ç»Ÿï¼ˆåŠå…¶åº”用开å‘工具)ã€åº”用程åºå’Œæ•°æ®åº“管ç†å‘˜ï¼ˆDataBase Administrator DBA)组æˆçš„å˜å‚¨ã€ç®¡ç†ã€å¤„ç†å’Œç»´æŠ¤æ•°æ®çš„系统。
- 实体(entity):客观å˜åœ¨å¹¶å¯ç›¸äº’区别的事物称为实体。
- 属性(attribute):实体所具有的æŸä¸€ç‰¹æ€§ç§°ä¸ºå±žæ€§ã€‚
- ç (keyï¼‰ï¼šå”¯ä¸€æ ‡è¯†å®žä½“çš„å±žæ€§é›†ç§°ä¸ºç 。
- 实体型(entity type):用实体ååŠå…¶å±žæ€§åé›†åˆæ¥æŠ½è±¡å’Œåˆ»ç”»åŒç±»å®žä½“,称为实体型。
- 实体集(entity set):åŒä¸€å®žä½“型的集åˆç§°ä¸ºå®žä½“集。
- è”系(relationship):实体之间的è”系通常是指ä¸åŒå®žä½“集之间的è”系。
- 模å¼ï¼ˆschema):模å¼ä¹Ÿç§°é€»è¾‘模å¼ï¼Œæ˜¯æ•°æ®åº“全体数æ®çš„逻辑结构和特å¾çš„æè¿°ï¼Œæ˜¯æ‰€æœ‰ç”¨æˆ·çš„公共数æ®è§†å›¾ã€‚
- 外模å¼ï¼ˆexternal schema):外模å¼ä¹Ÿç§°å模å¼ï¼ˆsubschema)或用户模å¼ï¼Œå®ƒæ˜¯æ•°æ®åº“用户(包括应用程åºå‘˜å’Œæœ€ç»ˆç”¨æˆ·ï¼‰èƒ½å¤Ÿçœ‹è§å’Œä½¿ç”¨çš„局部数æ®çš„逻辑结构和特å¾çš„æè¿°ï¼Œæ˜¯æ•°æ®åº“用户的数æ®è§†å›¾ï¼Œæ˜¯ä¸ŽæŸä¸€åº”用有关的数æ®çš„逻辑表示。
- 内模å¼ï¼ˆinternal schema):内模å¼ä¹Ÿç§°ä¸ºå˜å‚¨æ¨¡å¼ï¼ˆstorage schema),一个数æ®åº“åªæœ‰ä¸€ä¸ªå†…模å¼ã€‚他是数æ®ç‰©ç†ç»“构和å˜å‚¨æ–¹å¼çš„æè¿°ï¼Œæ˜¯æ•°æ®åº“在数æ®åº“内部的组织方å¼ã€‚
- 层次模型(hierarchical model)
- 网状模型(network model)
- 关系模型(relational model)
- 关系(relationï¼‰ï¼šä¸€ä¸ªå…³ç³»å¯¹åº”é€šå¸¸è¯´çš„ä¸€å¼ è¡¨
- 元组(tuple):表ä¸çš„一行å³ä¸ºä¸€ä¸ªå…ƒç»„
- 属性(attribute):表ä¸çš„一列å³ä¸ºä¸€ä¸ªå±žæ€§
- ç (key):表ä¸å¯ä»¥å”¯ä¸€ç¡®å®šä¸€ä¸ªå…ƒç»„çš„æŸä¸ªå±žæ€§ç»„
- 域(domainï¼‰ï¼šä¸€ç»„å…·æœ‰ç›¸åŒæ•°æ®ç±»åž‹çš„值的集åˆ
- 分é‡ï¼šå…ƒç»„ä¸çš„一个属性值
- 关系模å¼ï¼šå¯¹å…³ç³»çš„æè¿°ï¼Œä¸€èˆ¬è¡¨ç¤ºä¸º
关系å(属性1, 属性2, ..., 属性n)
- é¢å‘å¯¹è±¡æ•°æ®æ¨¡åž‹ï¼ˆobject oriented data model)
- å¯¹è±¡å…³ç³»æ•°æ®æ¨¡åž‹ï¼ˆobject relational data model)
- åŠç»“æž„åŒ–æ•°æ®æ¨¡åž‹ï¼ˆsemistructure data model)
对象类型 | 对象 | æ“作类型 |
---|---|---|
æ•°æ®åº“æ¨¡å¼ | æ¨¡å¼ | CREATE SCHEMA |
基本表 | CREATE SCHEMA ,ALTER TABLE |
|
视图 | CREATE VIEW |
|
索引 | CREATE INDEX |
|
æ•°æ® | 基本表和视图 | SELECT ,INSERT ,UPDATE ,DELETE ,REFERENCES ,ALL PRIVILEGES |
属性列 | SELECT ,INSERT ,UPDATE ,REFERENCES ,ALL PRIVILEGES |
SQL è¯æ³•教程:runoob . SQL 教程
- 基本关系æ“ä½œï¼šæŸ¥è¯¢ï¼ˆé€‰æ‹©ã€æŠ•å½±ã€è¿žæŽ¥ï¼ˆç‰å€¼è¿žæŽ¥ã€è‡ªç„¶è¿žæŽ¥ã€å¤–连接(左外连接ã€å³å¤–连接))ã€é™¤ã€å¹¶ã€å·®ã€äº¤ã€ç¬›å¡å°”积ç‰ï¼‰ã€æ’å…¥ã€åˆ 除ã€ä¿®æ”¹
- 关系模型ä¸çš„三类完整性约æŸï¼šå®žä½“完整性ã€å‚照完整性ã€ç”¨æˆ·å®šä¹‰çš„完整性
- æ•°æ®åº“索引:顺åºç´¢å¼•ã€B+ æ ‘ç´¢å¼•ã€hash 索引
- MySQL 索引背åŽçš„æ•°æ®ç»“æž„åŠç®—法原ç†
- æ•°æ®åº“的完整性是指数æ®çš„æ£ç¡®æ€§å’Œç›¸å®¹æ€§ã€‚
- å®Œæ•´æ€§ï¼šä¸ºäº†é˜²æ¢æ•°æ®åº“ä¸å˜åœ¨ä¸ç¬¦åˆè¯ä¹‰ï¼ˆä¸æ£ç¡®ï¼‰çš„æ•°æ®ã€‚
- å®‰å…¨æ€§ï¼šä¸ºäº†ä¿æŠ¤æ•°æ®åº“é˜²æ¢æ¶æ„ç ´åå’Œéžæ³•å˜å–。
- 触å‘器:是用户定义在关系表ä¸çš„一类由事件驱动的特殊过程。
- æ•°æ®ä¾èµ–是一个关系内部属性与属性之间的一ç§çº¦æŸå…³ç³»ï¼Œæ˜¯é€šè¿‡å±žæ€§é—´å€¼çš„相ç‰ä¸Žå¦ä½“现出æ¥çš„æ•°æ®é—´ç›¸å…³è”系。
- 最é‡è¦çš„æ•°æ®ä¾èµ–:函数ä¾èµ–ã€å¤šå€¼ä¾èµ–。
- 第一范å¼ï¼ˆ1NFï¼‰ï¼šå±žæ€§ï¼ˆå—æ®µï¼‰æ˜¯æœ€å°å•ä½ä¸å¯å†åˆ†ã€‚
- 第二范å¼ï¼ˆ2NF):满足 1NF,æ¯ä¸ªéžä¸»å±žæ€§å®Œå…¨ä¾èµ–于主键(消除 1NF éžä¸»å±žæ€§å¯¹ç 的部分函数ä¾èµ–)。
- 第三范å¼ï¼ˆ3NF):满足 2NF,任何éžä¸»å±žæ€§ä¸ä¾èµ–于其他éžä¸»å±žæ€§ï¼ˆæ¶ˆé™¤ 2NF éžä¸»å±žæ€§å¯¹ç çš„ä¼ é€’å‡½æ•°ä¾èµ–)。
- é²ä¾æ–¯-科得范å¼ï¼ˆBCNF):满足 3NF,任何éžä¸»å±žæ€§ä¸èƒ½å¯¹ä¸»é”®å集ä¾èµ–(消除 3NF 主属性对ç çš„éƒ¨åˆ†å’Œä¼ é€’å‡½æ•°ä¾èµ–)。
- 第四范å¼ï¼ˆ4NF):满足 3NF,属性之间ä¸èƒ½æœ‰éžå¹³å‡¡ä¸”éžå‡½æ•°ä¾èµ–的多值ä¾èµ–(消除 3NF éžå¹³å‡¡ä¸”éžå‡½æ•°ä¾èµ–的多值ä¾èµ–)。
- 事务:是用户定义的一个数æ®åº“æ“作åºåˆ—,这些æ“作è¦ä¹ˆå…¨åšï¼Œè¦ä¹ˆå…¨ä¸åšï¼Œæ˜¯ä¸€ä¸ªä¸å¯åˆ†å‰²çš„工作å•ä½ã€‚
- 事物的 ACID ç‰¹æ€§ï¼šåŽŸåæ€§ã€ä¸€è‡´æ€§ã€éš”ç¦»æ€§ã€æŒç»æ€§ã€‚
- æ¢å¤çš„å®žçŽ°æŠ€æœ¯ï¼šå»ºç«‹å†—ä½™æ•°æ® -> 利用冗余数æ®å®žæ–½æ•°æ®åº“æ¢å¤ã€‚
- 建立冗余数æ®å¸¸ç”¨æŠ€æœ¯ï¼šæ•°æ®è½¬å‚¨ï¼ˆåŠ¨æ€æµ·é‡è½¬å‚¨ã€åЍæ€å¢žé‡è½¬å‚¨ã€é™æ€æµ·é‡è½¬å‚¨ã€é™æ€å¢žé‡è½¬å‚¨ï¼‰ã€ç™»è®°æ—¥å¿—文件。
- äº‹åŠ¡æ˜¯å¹¶å‘æŽ§åˆ¶çš„åŸºæœ¬å•ä½ã€‚
- 并呿“作带æ¥çš„æ•°æ®ä¸ä¸€è‡´æ€§åŒ…括:丢失修改ã€ä¸å¯é‡å¤è¯»ã€è¯» “脆数æ®ã€‚
- å¹¶å‘æŽ§åˆ¶ä¸»è¦æŠ€æœ¯ï¼šå°é”ã€æ—¶é—´æˆ³ã€ä¹è§‚控制法ã€å¤šç‰ˆæœ¬å¹¶å‘控制ç‰ã€‚
- 基本å°é”类型:排他é”(X é” / 写é”)ã€å…±äº«é”(S é” / 读é”)。
- æ´»é”æ»é”:
- æ´»é”:事务永远处于ç‰å¾…状æ€ï¼Œå¯é€šè¿‡å…ˆæ¥å…ˆæœåŠ¡çš„ç–ç•¥é¿å…。
- æ»é”:事务永远ä¸èƒ½ç»“æŸ
- 预防:一次å°é”法ã€é¡ºåºå°é”法;
- 诊æ–:超时法ã€ç‰å¾…图法;
- è§£é™¤ï¼šæ’¤é”€å¤„ç†æ»é”代价最å°çš„事务,并释放æ¤äº‹åŠ¡çš„æ‰€æœ‰çš„é”,使其他事务得以继ç»è¿è¡Œä¸‹åŽ»ã€‚
- å¯ä¸²è¡ŒåŒ–è°ƒåº¦ï¼šå¤šä¸ªäº‹åŠ¡çš„å¹¶å‘æ‰§è¡Œæ˜¯æ£ç¡®çš„,当且仅当其结果与按æŸä¸€æ¬¡åºä¸²è¡Œåœ°æ‰§è¡Œè¿™äº›äº‹åŠ¡æ—¶çš„ç»“æžœç›¸åŒã€‚å¯ä¸²è¡Œæ€§æ—¶å¹¶å‘事务æ£ç¡®è°ƒåº¦çš„准则。
å„大设计模å¼ä¾‹åå‚考:CSDN专æ . C++ è®¾è®¡æ¨¡å¼ ç³»åˆ—åšæ–‡
- å•一èŒè´£åŽŸåˆ™ï¼ˆSRP,Single Responsibility Principle)
- é‡Œæ°æ›¿æ¢åŽŸåˆ™ï¼ˆLSP,Liskov Substitution Principle)
- ä¾èµ–倒置原则(DIP,Dependence Inversion Principle)
- 接å£éš”离原则(ISP,Interface Segregation Principle)
- 迪米特法则(LoD,Law of Demeter)
- 开放å°é—原则(OCP,Open Close Principle)
本节部分知识点æ¥è‡ªã€Šç¨‹åºå‘˜çš„自我修养——链接装载库》
一般应用程åºå†…å˜ç©ºé—´æœ‰å¦‚下区域:
- æ ˆï¼šç”±æ“作系统自动分é…é‡Šæ”¾ï¼Œå˜æ”¾å‡½æ•°çš„傿•°å€¼ã€å±€éƒ¨å˜é‡ç‰çš„值,用于维护函数调用的上下文
- å †ï¼šä¸€èˆ¬ç”±ç¨‹åºå‘˜åˆ†é…释放,若程åºå‘˜ä¸é‡Šæ”¾ï¼Œç¨‹åºç»“æŸæ—¶å¯èƒ½ç”±æ“作系统回收,用æ¥å®¹çº³åº”用程åºåЍæ€åˆ†é…的内å˜åŒºåŸŸ
- 坿‰§è¡Œæ–‡ä»¶æ˜ åƒï¼šå˜å‚¨ç€å¯æ‰§è¡Œæ–‡ä»¶åœ¨å†…å˜ä¸çš„æ˜ åƒï¼Œç”±è£…è½½å™¨è£…è½½æ˜¯å°†å¯æ‰§è¡Œæ–‡ä»¶çš„内å˜è¯»å–æˆ–æ˜ å°„åˆ°è¿™é‡Œ
- ä¿ç•™åŒºï¼šä¿ç•™åŒºå¹¶ä¸æ˜¯ä¸€ä¸ªå•一的内å˜åŒºåŸŸï¼Œè€Œæ˜¯å¯¹å†…å˜ä¸å—åˆ°ä¿æŠ¤è€Œç¦æ¢è®¿é—®çš„内å˜åŒºåŸŸçš„æ€»ç§°ï¼Œå¦‚通常 C è¯è¨€è®²æ— 效指针赋值为 0(NULLï¼‰ï¼Œå› æ¤ 0 åœ°å€æ£å¸¸æƒ…况下ä¸å¯èƒ½æœ‰æ•ˆçš„访问数æ®
æ ˆä¿å˜äº†ä¸€ä¸ªå‡½æ•°è°ƒç”¨æ‰€éœ€è¦çš„维护信æ¯ï¼Œå¸¸è¢«ç§°ä¸ºå †æ ˆå¸§ï¼ˆStack Frame)或活动记录(Activate Record),一般包å«ä»¥ä¸‹å‡ æ–¹é¢ï¼š
- 函数的返回地å€å’Œå‚æ•°
- 临时å˜é‡ï¼šåŒ…括函数的éžé™æ€å±€éƒ¨å˜é‡ä»¥åŠç¼–译器自动生æˆçš„其他临时å˜é‡
- ä¿å˜ä¸Šä¸‹æ–‡ï¼šåŒ…括函数调用å‰åŽéœ€è¦ä¿æŒä¸å˜çš„寄å˜å™¨
å †åˆ†é…算法:
- 空闲链表(Free List)
- ä½å›¾ï¼ˆBitmap)
- 对象æ±
å…¸åž‹çš„éžæ³•æŒ‡é’ˆè§£å¼•ç”¨é€ æˆçš„错误。当指针指å‘一个ä¸å…许读写的内å˜åœ°å€ï¼Œè€Œç¨‹åºå´è¯•图利用指针æ¥è¯»æˆ–å†™è¯¥åœ°å€æ—¶ï¼Œä¼šå‡ºçŽ°è¿™ä¸ªé”™è¯¯ã€‚
æ™®éåŽŸå› ï¼š
- 将指针åˆå§‹åŒ–为 NULLï¼Œä¹‹åŽæ²¡æœ‰ç»™å®ƒä¸€ä¸ªåˆç†çš„值就开始使用指针
- 没用åˆå§‹åŒ–æ ˆä¸çš„æŒ‡é’ˆï¼ŒæŒ‡é’ˆçš„å€¼ä¸€èˆ¬ä¼šæ˜¯éšæœºæ•°ï¼Œä¹‹åŽå°±ç›´æŽ¥å¼€å§‹ä½¿ç”¨æŒ‡é’ˆ
å¹³å° | 坿‰§è¡Œæ–‡ä»¶ | ç›®æ ‡æ–‡ä»¶ | 动æ€åº“/共享对象 | 陿€åº“ |
---|---|---|---|---|
Windows | exe | obj | dll | lib |
Unix/Linux | ELFã€out | o | so | a |
Mac | Mach-O | o | dylibã€tbdã€framework | aã€framework |
- 预编译(预编译器处ç†å¦‚
#include
ã€#define
ç‰é¢„编译指令,生æˆ.i
或.ii
文件) - ç¼–è¯‘ï¼ˆç¼–è¯‘å™¨è¿›è¡Œè¯æ³•分æžã€è¯æ³•分æžã€è¯ä¹‰åˆ†æžã€ä¸é—´ä»£ç 生æˆã€ç›®æ ‡ä»£ç 生æˆã€ä¼˜åŒ–,生æˆ
.s
文件) - 汇编(汇编器把汇编ç ç¿»è¯‘æˆæœºå™¨ç ,生æˆ
.o
文件) - 链接(连接器进行地å€å’Œç©ºé—´åˆ†é…ã€ç¬¦å·å†³è®®ã€é‡å®šä½ï¼Œç”Ÿæˆ
.out
文件)
现在版本 GCC æŠŠé¢„ç¼–è¯‘å’Œç¼–è¯‘åˆæˆä¸€æ¥ï¼Œé¢„ç¼–è¯‘ç¼–è¯‘ç¨‹åº cc1ã€æ±‡ç¼–器 asã€è¿žæŽ¥å™¨ ld
MSVC 编译环境,编译器 clã€è¿žæŽ¥å™¨ linkã€å¯æ‰§è¡Œæ–‡ä»¶æŸ¥çœ‹å™¨ dumpbin
编译器编译æºä»£ç åŽç”Ÿæˆçš„æ–‡ä»¶å«åšç›®æ ‡æ–‡ä»¶ã€‚ç›®æ ‡æ–‡ä»¶ä»Žç»“æž„ä¸Šè®²ï¼Œå®ƒæ˜¯å·²ç»ç¼–译åŽçš„坿‰§è¡Œæ–‡ä»¶æ ¼å¼ï¼Œåªæ˜¯è¿˜æ²¡æœ‰ç»è¿‡é“¾æŽ¥çš„过程,其ä¸å¯èƒ½æœ‰äº›ç¬¦å·æˆ–有些地å€è¿˜æ²¡æœ‰è¢«è°ƒæ•´ã€‚
坿‰§è¡Œæ–‡ä»¶ï¼ˆWindows çš„
.exe
和 Linux 的ELF
)ã€åЍæ€é“¾æŽ¥åº“(Windows çš„.dll
和 Linux 的.so
)ã€é™æ€é“¾æŽ¥åº“(Windows çš„.lib
和 Linux 的.a
ï¼‰éƒ½æ˜¯æŒ‰ç…§å¯æ‰§è¡Œæ–‡ä»¶æ ¼å¼å˜å‚¨ï¼ˆWindows 按照 PE-COFF,Linux 按照 ELF)
- Windows 的 PE(Portable Executable),或称为 PE-COFF,
.obj
æ ¼å¼ - Linux çš„ ELF(Executable Linkable Format),
.o
æ ¼å¼ - Intel/Microsoft çš„ OMF(Object Module Format)
- Unix çš„
a.out
æ ¼å¼ - MS-DOS çš„
.COM
æ ¼å¼
PE å’Œ ELF 都是 COFF(Common File Format)的å˜ç§
段 | 功能 |
---|---|
File Header | 文件头,æè¿°æ•´ä¸ªæ–‡ä»¶çš„æ–‡ä»¶å±žæ€§ï¼ˆåŒ…括文件是å¦å¯æ‰§è¡Œã€æ˜¯é™æ€é“¾æŽ¥æˆ–动æ€è¿žæŽ¥åŠå…¥å£åœ°å€ã€ç›®æ ‡ç¡¬ä»¶ã€ç›®æ ‡æ“作系统ç‰ï¼‰ |
.text section | ä»£ç æ®µï¼Œæ‰§è¡Œè¯å¥ç¼–译æˆçš„æœºå™¨ä»£ç |
.data section | æ•°æ®æ®µï¼Œå·²åˆå§‹åŒ–的全局å˜é‡å’Œå±€éƒ¨é™æ€å˜é‡ |
.bss section | BSS 段(Block Started by Symbol),未åˆå§‹åŒ–的全局å˜é‡å’Œå±€éƒ¨é™æ€å˜é‡ï¼ˆå› 为默认值为 0ï¼Œæ‰€ä»¥åªæ˜¯åœ¨æ¤é¢„ç•™ä½ç½®ï¼Œä¸å 空间) |
.rodata section | åªè¯»æ•°æ®æ®µï¼Œå˜æ”¾åªè¯»æ•°æ®ï¼Œä¸€èˆ¬æ˜¯ç¨‹åºé‡Œé¢çš„åªè¯»å˜é‡ï¼ˆå¦‚ const 修饰的å˜é‡ï¼‰å’Œå—ç¬¦ä¸²å¸¸é‡ |
.comment section | æ³¨é‡Šä¿¡æ¯æ®µï¼Œå˜æ”¾ç¼–è¯‘å™¨ç‰ˆæœ¬ä¿¡æ¯ |
.note.GNU-stack section | å †æ ˆæç¤ºæ®µ |
其他段略
在链接ä¸ï¼Œç›®æ ‡æ–‡ä»¶ä¹‹é—´ç›¸äº’拼åˆå®žé™…ä¸Šæ˜¯ç›®æ ‡æ–‡ä»¶ä¹‹é—´å¯¹åœ°å€çš„引用,å³å¯¹å‡½æ•°å’Œå˜é‡çš„地å€çš„引用。我们将函数和å˜é‡ç»Ÿç§°ä¸ºç¬¦å·ï¼ˆSymbolï¼‰ï¼Œå‡½æ•°åæˆ–å˜é‡å就是符å·å(Symbol Name)。
如下符å·è¡¨ï¼ˆSymbol Table):
Symbol(符å·å) | Symbol Value (地å€ï¼‰ |
---|---|
main | 0x100 |
Add | 0x123 |
... | ... |
Linux 下的共享库就是普通的 ELF 共享对象。
共享库版本更新应该ä¿è¯äºŒè¿›åˆ¶æŽ¥å£ ABI(Application Binary Interface)的兼容
libname.so.x.y.z
- x:主版本å·ï¼Œä¸åŒä¸»ç‰ˆæœ¬å·çš„库之间ä¸å…¼å®¹ï¼Œéœ€è¦é‡æ–°ç¼–译
- y:次版本å·ï¼Œé«˜ç‰ˆæœ¬å·å‘åŽå…¼å®¹ä½Žç‰ˆæœ¬å·
- z:å‘布版本å·ï¼Œä¸å¯¹æŽ¥å£è¿›è¡Œæ›´æ”¹ï¼Œå®Œå…¨å…¼å®¹
大部分包括 Linux 在内的开æºç³»ç»Ÿéµå¾ª FHS(File Hierarchy Standardï¼‰çš„æ ‡å‡†ï¼Œè¿™æ ‡å‡†è§„å®šäº†ç³»ç»Ÿæ–‡ä»¶å¦‚ä½•å˜æ”¾ï¼ŒåŒ…括å„个目录结构ã€ç»„织和作用。
/lib
ï¼šå˜æ”¾ç³»ç»Ÿæœ€å…³é”®å’Œæœ€åŸºç¡€çš„共享库,如动æ€é“¾æŽ¥å™¨ã€C è¯è¨€è¿è¡Œåº“ã€æ•°å¦åº“ç‰/usr/lib
ï¼šå˜æ”¾éžç³»ç»Ÿè¿è¡Œæ—¶æ‰€éœ€è¦çš„å…³é”®æ€§çš„åº“ï¼Œä¸»è¦æ˜¯å¼€å‘库/usr/local/lib
ï¼šå˜æ”¾è·Ÿæ“作系统本身并ä¸ååˆ†ç›¸å…³çš„åº“ï¼Œä¸»è¦æ˜¯ä¸€äº›ç¬¬ä¸‰æ–¹åº”用程åºçš„库
动æ€é“¾æŽ¥å™¨ä¼šåœ¨
/lib
ã€/usr/lib
和由/etc/ld.so.conf
é…ç½®æ–‡ä»¶æŒ‡å®šçš„ï¼Œç›®å½•ä¸æŸ¥æ‰¾å…±äº«åº“
LD_LIBRARY_PATH
ï¼šä¸´æ—¶æ”¹å˜æŸä¸ªåº”用程åºçš„共享库查找路径,而ä¸ä¼šå½±å“其他应用程åºLD_PRELOAD
ï¼šæŒ‡å®šé¢„å…ˆè£…è½½çš„ä¸€äº›å…±äº«åº“ç”šè‡³æ˜¯ç›®æ ‡æ–‡ä»¶LD_DEBUG
:打开动æ€é“¾æŽ¥å™¨çš„调试功能
使用 CLion 编写共享库
创建一个å为 MySharedLib 的共享库
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MySharedLib)
set(CMAKE_CXX_STANDARD 11)
add_library(MySharedLib SHARED library.cpp library.h)
library.h
#ifndef MYSHAREDLIB_LIBRARY_H
#define MYSHAREDLIB_LIBRARY_H
// æ‰“å° Hello World!
void hello();
// 使用å¯å˜æ¨¡ç‰ˆå‚数求和
template <typename T>
T sum(T t)
{
return t;
}
template <typename T, typename ...Types>
T sum(T first, Types ... rest)
{
return first + sum<T>(rest...);
}
#endif
library.cpp
#include <iostream>
#include "library.h"
void hello() {
std::cout << "Hello, World!" << std::endl;
}
使用 CLion 调用共享库
创建一个å为 TestSharedLib çš„å¯æ‰§è¡Œé¡¹ç›®
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(TestSharedLib)
# C++11 编译
set(CMAKE_CXX_STANDARD 11)
# 头文件路径
set(INC_DIR /home/xx/code/clion/MySharedLib)
# 库文件路径
set(LIB_DIR /home/xx/code/clion/MySharedLib/cmake-build-debug)
include_directories(${INC_DIR})
link_directories(${LIB_DIR})
link_libraries(MySharedLib)
add_executable(TestSharedLib main.cpp)
# 链接 MySharedLib 库
target_link_libraries(TestSharedLib MySharedLib)
main.cpp
#include <iostream>
#include "library.h"
using std::cout;
using std::endl;
int main() {
hello();
cout << "1 + 2 = " << sum(1,2) << endl;
cout << "1 + 2 + 3 = " << sum(1,2,3) << endl;
return 0;
}
执行结果
Hello, World!
1 + 2 = 3
1 + 2 + 3 = 6
- GUI(Graphical User Interface)应用,链接器选项:
/SUBSYSTEM:WINDOWS
- CUI(Console User Interface)应用,链接器选项:
/SUBSYSTEM:CONSOLE
_tWinMain 与 _tmain 函数声明
Int WINAPI _tWinMain(
HINSTANCE hInstanceExe,
HINSTANCE,
PTSTR pszCmdLine,
int nCmdShow);
int _tmain(
int argc,
TCHAR *argv[],
TCHAR *envp[]);
应用程åºç±»åž‹ | å…¥å£ç‚¹å‡½æ•° | åµŒå…¥å¯æ‰§è¡Œæ–‡ä»¶çš„å¯åŠ¨å‡½æ•° |
---|---|---|
处ç†ANSIå—符(串)的GUIåº”ç”¨ç¨‹åº | _tWinMain(WinMain) | WinMainCRTSartup |
处ç†Unicodeå—符(串)的GUIåº”ç”¨ç¨‹åº | _tWinMain(wWinMain) | wWinMainCRTSartup |
处ç†ANSIå—符(串)的CUI应用ç F438 ¨‹åº | _tmain(Main) | mainCRTSartup |
处ç†Unicodeå—符(串)的CUIåº”ç”¨ç¨‹åº | _tmain(wMain) | wmainCRTSartup |
动æ€é“¾æŽ¥åº“(Dynamic-Link Library) | DllMain | _DllMainCRTStartup |
部分知识点æ¥è‡ªã€ŠWindows æ ¸å¿ƒç¼–ç¨‹ï¼ˆç¬¬äº”ç‰ˆï¼‰ã€‹
- 扩展了应用程åºçš„特性
- 简化了项目管ç†
- 有助于节çœå†…å˜
- 促进了资æºçš„共享
- 促进了本地化
- 有助于解决平å°é—´çš„差异
- å¯ä»¥ç”¨äºŽç‰¹æ®Šç›®çš„
- 创建 DLL,事实上是在创建å¯ä¾›ä¸€ä¸ªå¯æ‰§è¡Œæ¨¡å—调用的函数
- å½“ä¸€ä¸ªæ¨¡å—æä¾›ä¸€ä¸ªå†…å˜åˆ†é…函数(mallocã€newï¼‰çš„æ—¶å€™ï¼Œå®ƒå¿…é¡»åŒæ—¶æä¾›å¦ä¸€ä¸ªå†…å˜é‡Šæ”¾å‡½æ•°ï¼ˆfreeã€delete)
- 在使用 C å’Œ C++ 混编的时候,è¦ä½¿ç”¨ extern "C" 修饰符
- 一个 DLL å¯ä»¥å¯¼å‡ºå‡½æ•°ã€å˜é‡ï¼ˆé¿å…导出)ã€C++ 类(导出导入需è¦åŒç¼–译器,å¦åˆ™é¿å…导出)
- DLL 模å—:cpp 文件ä¸çš„ __declspec(dllexport) 写在 include 头文件之å‰
- 调用 DLL çš„å¯æ‰§è¡Œæ¨¡å—:cpp 文件的 __declspec(dllimport) 之å‰ä¸åº”该定义 MYLIBAPI
- 包å«å¯æ‰§è¡Œæ–‡ä»¶çš„目录
- Windows 的系统目录,å¯ä»¥é€šè¿‡ GetSystemDirectory 得到
- 16 ä½çš„ç³»ç»Ÿç›®å½•ï¼Œå³ Windows 目录ä¸çš„ System å目录
- Windows 目录,å¯ä»¥é€šè¿‡ GetWindowsDirectory 得到
- 进程的当å‰ç›®å½•
- PATH 环境å˜é‡ä¸æ‰€åˆ—出的目录
DllMain 函数
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
// 第一次将一个DLLæ˜ å°„åˆ°è¿›ç¨‹åœ°å€ç©ºé—´æ—¶è°ƒç”¨
// The DLL is being mapped into the process' address space.
break;
case DLL_THREAD_ATTACH:
// 当进程创建一个线程的时候,用于告诉DLL执行与线程相关的åˆå§‹åŒ–(éžä¸»çº¿ç¨‹æ‰§è¡Œï¼‰
// A thread is bing created.
break;
case DLL_THREAD_DETACH:
// 系统调用 ExitThread 线程退出å‰ï¼Œå³å°†ç»ˆæ¢çš„线程通过告诉DLL执行与线程相关的清ç†
// A thread is exiting cleanly.
break;
case DLL_PROCESS_DETACH:
// 将一个DLL从进程的地å€ç©ºé—´æ—¶è°ƒç”¨
// The DLL is being unmapped from the process' address space.
break;
}
return (TRUE); // Used only for DLL_PROCESS_ATTACH
}
LoadLibraryã€LoadLibraryExAã€LoadPackagedLibraryã€FreeLibraryã€FreeLibraryAndExitThread 函数声明
// 载入库
HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);
HMODULE LoadLibraryExA(
LPCSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags
);
// è‹¥è¦åœ¨é€šç”¨ Windows å¹³å°ï¼ˆUWP)应用ä¸åŠ è½½ Win32 DLL,需è¦è°ƒç”¨ LoadPackagedLibraryï¼Œè€Œä¸æ˜¯ LoadLibrary 或 LoadLibraryEx
HMODULE LoadPackagedLibrary(
LPCWSTR lpwLibFileName,
DWORD Reserved
);
// å¸è½½åº“
BOOL WINAPI FreeLibrary(
_In_ HMODULE hModule
);
// å¸è½½åº“和退出线程
VOID WINAPI FreeLibraryAndExitThread(
_In_ HMODULE hModule,
_In_ DWORD dwExitCode
);
GetProcAddress 函数声明
FARPROC GetProcAddress(
HMODULE hInstDll,
PCSTR pszSymbolName // åªèƒ½æŽ¥å— ANSI å—符串,ä¸èƒ½æ˜¯ Unicode
);
在 VS 的开å‘人员命令æç¤ºç¬¦
使用 DumpBin.exe
坿Ÿ¥çœ‹ DLL 库的导出段(导出的å˜é‡ã€å‡½æ•°ã€ç±»å的符å·ï¼‰ã€ç›¸å¯¹è™šæ‹Ÿåœ°å€ï¼ˆRVA,relative virtual address)。如:
DUMPBIN -exports D:\mydll.dll
LoadLibrary 与 FreeLibrary æµç¨‹å›¾
DLL 库的编写(导出一个 DLL 模å—) DLL 头文件
// MyLib.h
#ifdef MYLIBAPI
// MYLIBAPI 应该在全部 DLL æºæ–‡ä»¶çš„ include "Mylib.h" 之å‰è¢«å®šä¹‰
// 全部函数/å˜é‡æ£åœ¨è¢«å¯¼å‡º
#else
// 这个头文件被一个exeæºä»£ç 模å—包å«ï¼Œæ„味ç€å…¨éƒ¨å‡½æ•°/å˜é‡è¢«å¯¼å…¥
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
// 这里定义任何的数æ®ç»“构和符å·
// 定义导出的å˜é‡ï¼ˆé¿å…导出å˜é‡ï¼‰
MYLIBAPI int g_nResult;
// 定义导出函数原型
MYLIBAPI int Add(int nLeft, int nRight);
DLL æºæ–‡ä»¶
// MyLibFile1.cpp
// åŒ…å«æ ‡å‡†Windowså’ŒCè¿è¡Œæ—¶å¤´æ–‡ä»¶
#include <windows.h>
// DLLæºç 文件导出的函数和å˜é‡
#define MYLIBAPI extern "C" __declspec(dllexport)
// 包å«å¯¼å‡ºçš„æ•°æ®ç»“æž„ã€ç¬¦å·ã€å‡½æ•°ã€å˜é‡
#include "MyLib.h"
// å°†æ¤DLLæºä»£ç æ–‡ä»¶çš„ä»£ç æ”¾åœ¨æ¤å¤„
int g_nResult;
int Add(int nLeft, int nRight)
{
g_nResult = nLeft + nRight;
return g_nResult;
}
DLL 库的使用(è¿è¡Œæ—¶åЍæ€é“¾æŽ¥ DLL)
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
#include <windows.h>
#include <stdio.h>
typedef int (__cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("MyPuts.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
- æ“作系统创建进程,把控制æƒäº¤ç»™ç¨‹åºçš„å…¥å£ï¼ˆå¾€å¾€æ˜¯è¿è¡Œåº“ä¸çš„æŸä¸ªå…¥å£å‡½æ•°ï¼‰
- å…¥å£å‡½æ•°å¯¹è¿è¡Œåº“和程åºè¿è¡ŒçŽ¯å¢ƒè¿›è¡Œåˆå§‹åŒ–ï¼ˆåŒ…æ‹¬å †ã€I/Oã€çº¿ç¨‹ã€å…¨å±€å˜é‡æž„é€ ç‰ç‰ï¼‰ã€‚
- å…¥å£å‡½æ•°åˆå§‹åŒ–åŽï¼Œè°ƒç”¨ main 函数,æ£å¼å¼€å§‹æ‰§è¡Œç¨‹åºä¸»ä½“部分。
- main 函数执行完毕åŽï¼Œè¿”回到入å£å‡½æ•°è¿›è¡Œæ¸…ç†å·¥ä½œï¼ˆåŒ…括全局å˜é‡æžæž„ã€å †é”€æ¯ã€å…³é—I/Oç‰ï¼‰ï¼Œç„¶åŽè¿›è¡Œç³»ç»Ÿè°ƒç”¨ç»“æŸè¿›ç¨‹ã€‚
一个程åºçš„ I/O 指代程åºä¸Žå¤–界的交互,包括文件ã€ç®¡ç¨‹ã€ç½‘络ã€å‘½ä»¤è¡Œã€ä¿¡å·ç‰ã€‚更广义地讲,I/O 指代æ“作系统ç†è§£ä¸º “文件†的事物。
_start -> __libc_start_main -> exit -> _exit
å…¶ä¸ main(argc, argv, __environ)
函数在 __libc_start_main
里执行。
int mainCRTStartup(void)
执行如下æ“作:
- åˆå§‹åŒ–å’Œ OS 版本有关的全局å˜é‡ã€‚
- åˆå§‹åŒ–å †ã€‚
- åˆå§‹åŒ– I/O。
- 获å–å‘½ä»¤è¡Œå‚æ•°å’ŒçŽ¯å¢ƒå˜é‡ã€‚
- åˆå§‹åŒ– C 库的一些数æ®ã€‚
- 调用 main 并记录返回值。
- 检查错误并将 main 的返回值返回。
大致包å«å¦‚下功能:
- å¯åŠ¨ä¸Žé€€å‡ºï¼šåŒ…æ‹¬å…¥å£å‡½æ•°åŠå…¥å£å‡½æ•°æ‰€ä¾èµ–的其他函数ç‰ã€‚
- æ ‡å‡†å‡½æ•°ï¼šæœ‰ C è¯è¨€æ ‡å‡†è§„定的Cè¯è¨€æ ‡å‡†åº“所拥有的函数实现。
- I/O:I/O 功能的å°è£…和实现。
- å †ï¼šå †çš„å°è£…和实现。
- è¯è¨€å®žçŽ°ï¼šè¯è¨€ä¸ä¸€äº›ç‰¹æ®ŠåŠŸèƒ½çš„å®žçŽ°ã€‚
- 调试:实现调试功能的代ç 。
包å«ï¼š
- æ ‡å‡†è¾“å…¥è¾“å‡ºï¼ˆstdio.h)
- 文件æ“作(stdio.h)
- å—符æ“作(ctype.h)
- å—符串æ“作(string.h)
- æ•°å¦å‡½æ•°ï¼ˆmath.h)
- 资æºç®¡ç†ï¼ˆstdlib.h)
- æ ¼å¼è½¬æ¢ï¼ˆstdlib.h)
- 时间/日期(time.h)
- æ–言(assert.h)
- å„ç§ç±»åž‹ä¸Šçš„常数(limits.h & float.h)
- å˜é•¿å‚数(stdarg.h)
- éžå±€éƒ¨è·³è½¬ï¼ˆsetjmp.h)
huihut/CS-Books:📚 Computer Science Books è®¡ç®—æœºæŠ€æœ¯ç±»ä¹¦ç± PDF
- 《C++ Primer》
- 《Effective C++》
- 《More Effective C++》
- 《深度探索 C++ 对象模型》
- 《深入ç†è§£ C++11》
- 《STL æºç 剖æžã€‹
- 《剑指 Offer》
- 《编程ç 玑》
- 《程åºå‘˜é¢è¯•å®å…¸ã€‹
- 《深入ç†è§£è®¡ç®—机系统》
- 《Windows æ ¸å¿ƒç¼–ç¨‹ã€‹
- 《Unix 环境高级编程》
- 《Unix 网络编程》
- 《TCP/IP 详解》
- 《程åºå‘˜çš„自我修养》
C/C++ å‘展方å‘甚广,包括ä¸é™äºŽä»¥ä¸‹æ–¹å‘, ä»¥ä¸‹åˆ—ä¸¾ä¸€äº›å¤§åŽ‚æ ¡æ‹›å²—ä½è¦æ±‚。
ã€åŽå°å¼€å‘】
- ç¼–ç¨‹åŸºæœ¬åŠŸæ‰Žå®žï¼ŒæŽŒæ¡ C/C++/JAVA ç‰å¼€å‘è¯è¨€ã€å¸¸ç”¨ç®—法和数æ®ç»“构;
- 熟悉 TCP/UDP 网络åè®®åŠç›¸å…³ç¼–程ã€è¿›ç¨‹é—´é€šè®¯ç¼–程;
- 了解 Pythonã€Shellã€Perl ç‰è„šæœ¬è¯è¨€ï¼›
- 了解 MYSQL åŠ SQL è¯è¨€ã€ç¼–程,了解 NoSQL, key-value å˜å‚¨åŽŸç†ï¼›
- å…¨é¢ã€æ‰Žå®žçš„è½¯ä»¶çŸ¥è¯†ç»“æž„ï¼ŒæŽŒæ¡æ“作系统ã€è½¯ä»¶å·¥ç¨‹ã€è®¾è®¡æ¨¡å¼ã€æ•°æ®ç»“æž„ã€æ•°æ®åº“系统ã€ç½‘络安全ç‰ä¸“业知识;
- 了解分布å¼ç³»ç»Ÿè®¾è®¡ä¸Žå¼€å‘ã€è´Ÿè½½å‡è¡¡æŠ€æœ¯ï¼Œç³»ç»Ÿå®¹ç¾è®¾è®¡ï¼Œé«˜å¯ç”¨ç³»ç»Ÿç‰çŸ¥è¯†ã€‚
ã€PC 客户端开å‘】
- 计算机软件相关专业本科或以上å¦åŽ†ï¼Œçƒçˆ±ç¼–程,基础扎实,ç†è§£ç®—法和数æ®ç»“构相关知识;
- 熟悉 windows æ“作系统的内å˜ç®¡ç†ã€æ–‡ä»¶ç³»ç»Ÿã€è¿›ç¨‹çº¿ç¨‹è°ƒåº¦ï¼›
- 熟悉 MFC/windows 界é¢å®žçŽ°æœºåˆ¶ï¼Œç†Ÿç»ƒä½¿ç”¨ VC,精通 C/C++,熟练使用 STLï¼Œä»¥åŠ Windows 下网络编程ç»éªŒï¼›
- ç†Ÿç»ƒæŽŒæ¡ Windows 客户端开å‘ã€è°ƒè¯•,有 Windows 应用软件开å‘ç»éªŒä¼˜å…ˆï¼›
- 对于创新åŠè§£å†³å…·æœ‰æŒ‘战性的问题充满激情,具有良好的算法基础åŠç³»ç»Ÿåˆ†æžèƒ½åŠ›ã€‚
ã€æ¸¸æˆå®¢æˆ·ç«¯å¼€å‘】
- 计算机科å¦/工程相关专业本科或以上å¦åŽ†ï¼Œçƒçˆ±ç¼–程,基础扎实,ç†è§£ç®—æ³•ã€æ•°æ®ç»“æž„ã€è½¯ä»¶è®¾è®¡ç›¸å…³çŸ¥è¯†ï¼›
- 至少掌æ¡ä¸€ç§æ¸¸æˆå¼€å‘常用的编程è¯è¨€ï¼Œå…· C++/C# 编程ç»éªŒä¼˜å…ˆï¼›
- 具游æˆå¼•擎(如 Unityã€Unreal)使用ç»éªŒè€…优先;
- äº†è§£æŸæ–¹é¢çš„æ¸¸æˆå®¢æˆ·ç«¯æŠ€æœ¯ï¼ˆå¦‚图形ã€éŸ³é¢‘ã€åŠ¨ç”»ã€ç‰©ç†ã€äººå·¥æ™ºèƒ½ã€ç½‘ç»œåŒæ¥ï¼‰è€…优先考虑;
- 对于创新åŠè§£å†³å…·æœ‰æŒ‘战性的问题充满激情,有较强的å¦ä¹ 能力ã€åˆ†æžåŠè§£å†³é—®é¢˜èƒ½åŠ›ï¼Œå…·å¤‡è‰¯å¥½çš„å›¢é˜Ÿåˆä½œæ„识;
- 具阅读英文技术文档能力;
- çƒçˆ±æ¸¸æˆã€‚
ã€æµ‹è¯•å¼€å‘】
- 计算机或相关专业本科åŠä»¥ä¸Šå¦åŽ†ï¼›
- 一至两年的 C/C++/Python 或其他计算机è¯è¨€çš„编程ç»éªŒï¼›
- å…·å¤‡æ’°å†™æµ‹è¯•è®¡åˆ’ã€æµ‹è¯•用例ã€ä»¥åŠå®žçŽ°æ€§èƒ½å’Œå®‰å…¨ç‰æµ‹è¯•的能力;
- 具备实现自动化系统的能力;
- 具备定ä½è°ƒæŸ¥äº§å“缺陷能力ã€ä»¥åŠä»£ç 级别调试缺陷的能力;
- 工作主动积æžï¼Œæœ‰è´£ä»»å¿ƒï¼Œå…·æœ‰è‰¯å¥½çš„团队åˆä½œç²¾ç¥žã€‚
ã€å®‰å…¨æŠ€æœ¯ã€‘
- çƒçˆ±äº’è”网,对æ“作系统和网络安全有狂çƒçš„追求,专业ä¸é™ï¼›
- ç†Ÿæ‚‰æ¼æ´žæŒ–掘ã€ç½‘络安全攻防技术,了解常è§é»‘客攻击手法;
- 掌æ¡åŸºæœ¬å¼€å‘能力,熟练使用 C/C++ è¯è¨€ï¼›
- 对数æ®åº“ã€æ“作系统ã€ç½‘ç»œåŽŸç†æœ‰è¾ƒå¥½æŽŒæ¡ï¼›
- 具有软件逆å‘,网络安全攻防或安全系统开å‘ç»éªŒè€…优先。
ã€åµŒå…¥å¼åº”用开å‘】
- æœ‰è‰¯å¥½çš„ç¼–ç¨‹åŸºç¡€ï¼Œç†Ÿç»ƒæŽŒæ¡ C/C++ è¯è¨€ï¼›
- æŽŒæ¡æ“ä½œç³»ç»Ÿã€æ•°æ®ç»“æž„ç‰è½¯ä»¶å¼€å‘必备知识;
- 具备较强的沟通ç†è§£èƒ½åŠ›åŠè‰¯å¥½çš„团队åˆä½œæ„识;
- 有 Linux/Android 系统平å°çš„å¼€å‘ç»éªŒè€…优先。
ã€éŸ³è§†é¢‘ç¼–è§£ç 】
- 硕士åŠä»¥ä¸Šå¦åŽ†ï¼Œè®¡ç®—æœºã€ä¿¡å·å¤„ç†ã€æ•°å¦ã€ä¿¡æ¯ç±»åŠç›¸å…³ä¸“业和方å‘ï¼›
- 视频编解ç 基础扎实,熟常用的 HEVC 或 H264,有较好的数å—ä¿¡å·å¤„ç†åŸºç¡€ï¼›
- æŽŒæ¡ C/C++,代ç 能力强, ç†Ÿæ‚‰ä¸€ç§æ±‡ç¼–è¯è¨€å°¤ä½³ï¼›
- 较强的英文文献阅读能力;
- å¦ä¹ 能力强,具有团队å作精神,有较强的抗压能力。
ã€è®¡ç®—æœºè§†è§‰ç ”ç©¶ã€‘
- 计算机ã€åº”用数å¦ã€æ¨¡å¼è¯†åˆ«ã€äººå·¥æ™ºèƒ½ã€è‡ªæŽ§ã€ç»Ÿè®¡å¦ã€è¿ç¹å¦ã€ç”Ÿç‰©ä¿¡æ¯ã€ç‰©ç†å¦/é‡å计算ã€ç¥žç»ç§‘å¦ã€ç¤¾ä¼šå¦/心ç†å¦ç‰ä¸“业,图åƒå¤„ç†ã€æ¨¡å¼è¯†åˆ«ã€æœºå™¨å¦ä¹ ç›¸å…³ç ”ç©¶æ–¹å‘,本科åŠä»¥ä¸Šï¼Œåšå£«ä¼˜å…ˆï¼›
- 熟练掌æ¡è®¡ç®—机视觉和图åƒå¤„ç†ç›¸å…³çš„基本算法åŠåº”用;
- è¾ƒå¼ºçš„ç®—æ³•å®žçŽ°èƒ½åŠ›ï¼Œç†Ÿç»ƒæŽŒæ¡ C/C++ 编程,熟悉 Shell/Python/Matlab 至少一ç§ç¼–程è¯è¨€ï¼›
- åœ¨è®¡ç®—æœºè§†è§‰ã€æ¨¡å¼è¯†åˆ«ç‰å¦æœ¯ä¼šè®®æˆ–者期刊上å‘表论文ã€ç›¸å…³å›½é™…比赛获奖ã€åŠæœ‰ç›¸å…³ä¸“利者优先。
- 牛客网 . 2020ç§‹æ‹›é¢ç»å¤§æ±‡æ€»ï¼ï¼ˆå²—ä½åˆ’分)
- 牛客网 . ã€å¤‡æˆ˜ç§‹æ‹›ã€‘2020届秋招备战攻略
- 牛客网 . 2019æ ¡æ‹›é¢ç»å¤§æ±‡æ€»ï¼ã€æ¯æ—¥æ›´æ–°ä¸ã€‘
- 牛客网 . 2019æ ¡æ‹›æŠ€æœ¯ç±»å²—ä½é¢ç»æ±‡æ€»ã€æŠ€æœ¯ç±»ã€‘
- 牛客网 . 2018æ ¡æ‹›ç¬”è¯•çœŸé¢˜æ±‡æ€»
- 牛客网 . 2017ç§‹å£æ ¡å›æ‹›è˜ç¬”ç»é¢ç»ä¸“题汇总
- 牛客网 . å²ä¸Šæœ€å…¨2017春招é¢ç»å¤§åˆé›†ï¼ï¼
- 牛客网 . é¢è¯•题干货在æ¤
- 知乎 . 互è”网求èŒè·¯ä¸Šï¼Œä½ è§è¿‡å“ªäº›å†™å¾—很好ã€å¾ˆç”¨å¿ƒçš„é¢ç»ï¼Ÿæœ€å¥½èƒ½åˆ†äº«è‡ªå·±çš„é¢ç»ã€å¿ƒè·¯åŽ†ç¨‹ã€‚
- 知乎 . 互è”ç½‘å…¬å¸æœ€å¸¸è§çš„é¢è¯•算法题有哪些?
- CSDN . 免颿•´ç†çš„C++é¢è¯•题
- CSDN . ç™¾åº¦ç ”å‘ç±»é¢è¯•题(C++æ–¹å‘)
- CSDN . c++常è§é¢è¯•题30é“
- CSDN . 腾讯2016å®žä¹ ç”Ÿé¢è¯•ç»éªŒï¼ˆå·²ç»æ‹¿åˆ°offer)
- cnblogs . C++é¢è¯•集锦( é¢è¯•被问到的问题 )
- cnblogs . C/C++ 笔试ã€é¢è¯•题目大汇总
- cnblogs . 常è§C++é¢è¯•题åŠåŸºæœ¬çŸ¥è¯†ç‚¹æ€»ç»“(一)
- segmentfault . C++常è§é¢è¯•问题总结
- Github . CyC2018/Job-Recommend:🔎 互è”网内推信æ¯ï¼ˆç¤¾æ‹›ã€æ ¡æ‹›ã€å®žä¹ )
- Github . amusi/AI-Job-Recommend:国内公å¸äººå·¥æ™ºèƒ½æ–¹å‘ï¼ˆå«æœºå™¨å¦ä¹ ã€æ·±åº¦å¦ä¹ ã€è®¡ç®—机视觉和自然è¯è¨€å¤„ç†ï¼‰å²—ä½çš„æ‹›è˜ä¿¡æ¯ï¼ˆå«å…¨èŒã€å®žä¹ å’Œæ ¡æ‹›ï¼‰
本仓库éµå¾ª CC BY-NC-SA 4.0(署å - éžå•†ä¸šæ€§ä½¿ç”¨ - ç›¸åŒæ–¹å¼å…±äº«ï¼‰ å议,转载请注明出处,ä¸å¾—用于商业目的。