Git Product home page Git Product logo

forthespada / interviewguide Goto Github PK

View Code? Open in Web Editor NEW
5.0K 29.0 1.3K 378.3 MB

🔥🔥「InterviewGuide」是阿秀从校园->职场多年计算机自学过程的记录以及学弟学妹们计算机校招&秋招经验总结文章的汇总,包括但不限于C/C++ 、Golang、JavaScript、Vue、操作系统、数据结构、计算机网络、MySQL、Redis等学习总结,坚持学习,持续成长!

Home Page: https://interviewguide.cn/

License: Apache License 2.0

cpp java os interview interview-questions interview-preparation redis mysql system questions-and-answers

interviewguide's Introduction

logo

水滴石穿

Hi 小伙伴你好 👋我是阿秀

  • 😄 普通双非学校出身,计算机学习基本全靠自学,校招时拿下百度、华为、农业银行、字节跳动SP等中大厂offer,后于字节跳动抖音部门担任全栈研发工程师,主后端、兼前端。

  • 🌱 我的计算机自学经历:逆袭?NO!只是多了一点坚持!

  • 🤔 信奉持续学习、终生成长,毕业后机缘巧合下组建了一个计算机学习圈:点此了解阿秀的学习圈更多详情

你可以在下面这些平台找到我:

我的开源项目 🏆


  • AwesomeGithub🔥:收集 GitHub 上高质量、有趣、沙雕的开源项目(⊙_⊙)。
  • InterviewGuide🚀:阿秀从校园->职场多年计算机自学过程的笔记以及学弟学妹们秋招总结文章
  • CS-Books🚀:从本科->研究生->工作,这十余年来自己收集的计算机相关的经典书籍以及学习资源
  • developer-roadmap-zh-CN:互联网校招技术岗开发者学习路线图
  • MyPoorWebServer:基于C++ 实现的HTTP服务器
  • programmer-resume🚀:阿秀自己的计算机求职简历模板
  • Awsome-Courses🚀:国外MIT、CMU、PKU、THU等知名CS高校的计算课程列表....
  • E-commerce:京东、苏宁、国美全站数据抓取,1000W的商品链接+8000W的商品数据和评论数据

我的公众号

持续个人计算机学习、编程、校招、职场工作等原创技术文章,希望自己踩过的坑后来人不要再踩,自己学过的内容能够帮助后来人一步一个脚印得慢慢成长🌹🌹🌹!

微信搜索:「拓跋阿秀」第一时间围观,扫码后回复:宝贝,真的会送你一个宝贝~。

interviewguide's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

interviewguide's Issues

开始阅读该InterviewGuide之前,希望你能进来看看!

InterviewGuide 这个仓库是阿秀在2021届秋招结束之后开始开源并维护的,也就是我2020年研三找工作结束后开始有这个计划的,这个仓库脱胎于我个人秋招时期总结的学习笔记,我自己也是凭借这份笔记成功体验到一份 offer 收割机 的快乐。
毫不夸张的说,我能够以普通双非二本的学历拿到字节跳动SP 的offer,全是这个仓库的功劳!
阿秀个人秋招总结可看这篇文章,我的八个月C++自学经历可以看这篇文章,后来我将个人笔记整理开源出来,于是就有了这个仓库,初衷是造福每位像我这样普通学校的学生,希望他们找工作之路能够顺利一些~

后来有小伙伴说github仓库看着太别扭,于是就有了一个小网站

虽然它现在只有820颗star,但在我看来它就是我的孩子一样,是我慢慢走过来的一个证明!
衷心感谢每位帮助过项目的朋友,谢谢你们指出各种错误,有的是我的微信好友,有的则是网络世界里的虚拟网友。

最后,本仓库只适合于面试前突击和对自己已学过的知识点进行查漏补缺,并不适合系统用来学习!
我说过很多遍了,真想学会知识,是要下功夫一点一点啃经典书籍、撸代码的!

送大家两句话:
1、你只管努力,剩下的交给时间就好,我就是最好的例子❤!
2、人生最可怕的莫过于在别人放弃你之前,先放弃了你自己!
各位老哥!加油!

InterviewGuide 勘误

错误题目 : 精选力扣300+题目之字符串 Easy 859. 亲密字符串
具体内容 : 第二版参考答案

bool buddyStrings(string A, string B) {
    if (A.size() != B.size() || A.size() < 2) return false;
    int len = A.size();
    vector<int> res;
    res.reserve(len);
    for (int i = 0; i < len; ++i)
    {
        if (A[i] != B[i])
        {
            res.push_back(i);
            if (res.size() > 2) return false;
        }
    }
    

    if (res.size() == 0)
    {
        unordered_set<char> misMatch(A.begin(), A.end());
        return misMatch.size() < len;
    }
    return A[res[0]] == B[res[1]] && A[res[1]] == B[res[0]];
}

测试用例"abcb""abcd"res.size()1时,缺少判断return false导致res[1]报错,故应添加一行代码如下:
if (res.size() == 1) return false;

勘误:c++基础语法【37、public,protected和private访问和继承权限/public/protected/private的区别?】以及【40、什么情况下会调用拷贝构造函数】

二、继承权限

派生类继承自基类的成员权限有四种状态:public、protected、private、不可见
派生类对基类成员的访问权限取决于两点:一、继承方式;二、基类成员在基类中的访问权限
派生类对基类成员的访问权限是取以上两点中的更小的访问范围(除了 private 的继承方式遇到 private 成员是不可见外)。例如:
public 继承 + private 成员 => private
private 继承 + protected 成员 => private
private 继承 + private 成员 => 不可见

倒数第三行

public 继承 + private 成员 => private

应当改为

public 继承 + private 成员 => 不可见

基类的private成员无论哪种继承方式都是不可见的

【功能添加】思维导图添加

使用mindmaster可以根据.md文件输出思维导图,节省画图时间。

具体使用方法:

  1. 编辑保存.md格式markdown笔记
  2. 打开mindmaster,点击“导入->导入markdown文件”
  3. 自动生成思维导图

必须使用初始化列表部分

“调用一个基类的构造函数,而该函数有一组参数。“这一条,应该是不必要的,或者我认为您想表达的是”子类初始化父类的私有成员,需要在(并且也只能在)参数初始化列表中显示调用父类的构造函数“

C++基础语法:“33、C++ 中的重载、重写(覆盖)和隐藏的区别”(补充)

// 父类
class A {
public:
    virtual void fun(int a) { // 虚函数
        cout << "This is A fun " << a << endl;
    }  
    void add(int a, int b) {
        cout << "This is A add " << a + b << endl;
    }
};

// 子类
class B: public A {
public:
    void fun(int a) override {  // 覆盖
        cout << "this is B fun " << a << endl;
    }
    void add(int a) {   // 隐藏
        cout << "This is B add " << a + a << endl;
    }
};

int main() {
    // 基类指针指向派生类对象时,基类指针可以直接调用到派生类的覆盖函数,也可以通过 :: 调用到基类被覆盖
    // 的虚函数;而基类指针只能调用基类的被隐藏函数,无法识别派生类中的隐藏函数。

    A *p = new B();
    p->fun(1);      // 调用子类 fun 覆盖函数
    p->A::fun(1);   // 调用父类 fun
    p->add(1, 2);
    // p->add(1);      // 错误,识别的是 A 类中的 add 函数,参数不匹配
    // p->B::add(1);   // 错误,无法识别子类 add 函数
    return 0;
}

请问是怎么实现导出PDF的?

请教作者大大,本项目要如何运行?我看也不是gitbook工程?再就是,在线网站中提供下载的PDF是你手动编写的,还是通过什么把markdown转化成pdf的呢?

计网 第30题 勘误

计网第30题, [网络的七层模型与各自的功能(图片版)] md图片格式错了

image

操作 系统勘误

43、一般情况下在Linux/windows平台下栈空间的大小
Linux环境下有操作系统决定,一般是8KB,8192kbytes,通过ulimit命令查看以及修改

8KB --> 8M

勘误说明

这份资料除去我在文末引用出处之外,其余部分均为阿秀个人原创,比如《带你快速刷完67道剑指offer》与《精选300+LeetCode题解》均为个人原创。
如果在看的您发现这份资料有些答案回答错误(逻辑错误或者原则性错误),欢迎提交 issue或者邮件告知,虚心接受每一位好心人的建议与意见。
您可以向阿秀邮箱 [email protected] 发邮件或者直接提交PR或者直接加我微信:aXiu_go说明即可,十分感谢!
如您发送邮件,格式如下:

  • 邮件标题:InterviewGuide 勘误
  • 邮件内容:
    • 错误题目,如C++第 1 题
    • 具体内容,具体的错误说明以及您认为的正确答案

若干修正建议

  • markdown 语法解析

    章节 1、在main执行之前和之后执行的代码可能是什么?

    attribute((constructor)) => __attribute__((constructor))

    attribute((destructor)) => __attribute__((destructor))


  • 内存对齐补充

    章节 2、结构体内存对齐问题?

    • c++11以后引入两个关键字alignasalignofalignof可以计算出类型的对齐方式。alignas可以指定结构体的对齐方式。但是alignas在某些情况下是不能使用的,具体见下面的例子:
    // alignas 生效的情况
    
    struct Info {
      uint8_t a;
      uint16_t b;
      uint8_t c;
    };
    
    std::cout << sizeof(Info) << std::endl;   // 6  2 + 2 + 2
    std::cout << alignof(Info) << std::endl;  // 2
    
    struct alignas(4) Info2 {
      uint8_t a;
      uint16_t b;
      uint8_t c;
    };
    
    std::cout << sizeof(Info2) << std::endl;   // 8  4 + 4
    std::cout << alignof(Info2) << std::endl;  // 4

    alignas将内存对齐调整为4个字节。所以sizeof(Info2)的值变为了8。

    // alignas 失效的情况
    
    struct Info {
      uint8_t a;
      uint32_t b;
      uint8_t c;
    };
    
    std::cout << sizeof(Info) << std::endl;   // 12  4 + 4 + 4
    std::cout << alignof(Info) << std::endl;  // 4
    
    struct alignas(2) Info2 {
      uint8_t a;
      uint32_t b;
      uint8_t c;
    };
    
    std::cout << sizeof(Info2) << std::endl;   // 12  4 + 4 + 4
    std::cout << alignof(Info2) << std::endl;  // 4

    alignas小于自然对齐的最小单位,则被忽略。

  • 如果想使用单字节对齐的方式,使用alignas是无效的。应该使用#pragma pack(push,1)或者使用__attribute__((packed))

    #if defined(__GNUC__) || defined(__GNUG__)
      #define ONEBYTE_ALIGN __attribute__((packed))
    #elif defined(_MSC_VER)
      #define ONEBYTE_ALIGN
      #pragma pack(push,1)
    #endif
    
    struct Info {
      uint8_t a;
      uint32_t b;
      uint8_t c;
    } ONEBYTE_ALIGN;
    
    #if defined(__GNUC__) || defined(__GNUG__)
      #undef ONEBYTE_ALIGN
    #elif defined(_MSC_VER)
      #pragma pack(pop)
      #undef ONEBYTE_ALIGN
    #endif
    
    std::cout << sizeof(Info) << std::endl;   // 6 1 + 4 + 1
    std::cout << alignof(Info) << std::endl;  // 6
  • 确定结构体中每个元素大小可以通过下面这种方法:

    #if defined(__GNUC__) || defined(__GNUG__)
      #define ONEBYTE_ALIGN __attribute__((packed))
    #elif defined(_MSC_VER)
      #define ONEBYTE_ALIGN
      #pragma pack(push,1)
    #endif
    
    /**
    * 
    * 0 1   3     6   8 9            15
    * +-+---+-----+---+-+-------------+
    * | |   |     |   | |             |
    * |a| b |  c  | d |e|     pad     |
    * | |   |     |   | |             |
    * +-+---+-----+---+-+-------------+
    *
    */
    struct Info {
      uint16_t a : 1;
      uint16_t b : 2;
      uint16_t c : 3;
      uint16_t d : 2;
      uint16_t e : 1;
      uint16_t pad : 7;
    } ONEBYTE_ALIGN;
    
    #if defined(__GNUC__) || defined(__GNUG__)
      #undef ONEBYTE_ALIGN
    #elif defined(_MSC_VER)
      #pragma pack(pop)
      #undef ONEBYTE_ALIGN
    #endif
    
    std::cout << sizeof(Info) << std::endl;   // 2
    std::cout << alignof(Info) << std::endl;  // 1

    这种处理方式是alignas处理不了的。


  • 虚函数问题

    33、为什么析构函数一般写成虚函数

    存在一种特例,在CRTP模板中,不应该将析构函数声明为虚函数,理论上所有的父类函数都不应
    该声明为虚函数,因为这种继承方式,不需要虚函数表。

    34、构造函数能否声明为虚函数或者纯虚函数,析构函数呢?

    构造函数不能声明为虚函数的原因之一如下:

    • 虚函数对应一个vtable(虚函数表),类中存储一个vptr指向这个vtable。如果构造函数是虚函数,就需要通过vtable调用,可是对象没有初始化就没有vptr,无法找到vtable,所以构造函数不能是虚函数。

  • 拼写错误

    45、什么情况下会调用拷贝构造函数

    总结就是:即使发生NRA优化的情况下, =》 总结就是:即使发生NRV优化的情况下,

InterviewGuide操作系统部分勘误

错误题目,操作系统第57.3 LRU算法画图
具体内容,LRU算法中图红框处圈出的八页面置换的位置写错了,应该是在隔壁的三处发生页面置换
image

InterviewGuide勘误

在C++基础知识40部分(什么情况下会调用拷贝构造函数):
image

此处的代码不够规范,含义模糊

A a1, a2, a3, a4;
A a2 = a1;

理由如下:
如果是上述代码,在Windows+vs2017(默认MSVC)下测试,“错误 C2374 “a2”: 重定义;多次初始化”
建议修改为:

A a1;
A a2 = a1;

InterviewGuide 勘误

错误/存疑题目

几个this指针的易混问题

具体内容

几个this指针的易混问题

中提到:

E.我们只有获得一个对象后,才能通过对象使用this指针。如果我们知道一个对象this指针的位置,可以直接使用吗?

this指针只有在成员函数中才有定义因此,你获得一个对象后,也不能通过对象使用this指针。所以,我们无法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。当然,在成员函数里,你是可以知道this指针的位置的(可以通过&this获得),也可以直接使用它。

而我在实际测试时发现使用&this后有如下错误:

test.cpp: In member function ‘void A::func()’:
test.cpp:10:25: error: lvalue required as unary ‘&’ operand
   10 |         A* const now = &this;
      |                         ^~~~

在StackOverFlow上找到解释如下提问:

https://stackoverflow.com/questions/56832986/is-it-possible-to-obtain-the-address-of-the-this-pointer

https://stackoverflow.com/questions/9114930/address-of-this

Quoting the 2003 C++ standard:

5.1 [expr.prim] The keyword this names a pointer to the object for which a nonstatic member function (9.3.2) is invoked. ... The type of the expression is a pointer to the function’s class (9.3.2), ... The expression is an rvalue.

this is not an lvalue.

The & requires an lvalue. lvalues are those that can appear on on the left-hand side of an assignment (variables, arrays, etc.).

Whereas this is a rvalue. rvalues can not appear on the left-hand side (addition, subtraction, etc.).

由SO回答可知根据c++标准this应当为右值, 无法通过&获取地址

由于我也是小白, 不知道如何准确对this做定义, 但我认为「当然,在成员函数里,你是可以知道this指针的位置的(可以通过&this获得),也可以直接使用它。」是有问题的。

C++基础语法:“24、C++中const和static的作用”(勘误)

错误说明:
static成员变量通常不应该在类内部初始化,但是有例外,就是常量的static成员变量。即static成员变量不是必须在类外初始化。
1

我认为的正确答案:
如果static成员变量不是常量(const或constexpr修饰的成员变量),不能在类声明中初始化,必须在类定义体外部初始化。

来源及代码验证:
C++ Primer 270页 “静态成员的类内初始化”:
2

代码:
3

数据库SQL第44题

两个事务不能锁同一个索引
改成
如果是共享锁,两个事务可以锁同一个索引,排它锁则不能。

C++第44题可能存在表述不清

mutable的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const函数里面修改一些跟类状态无关的数据成员,那么这个函数就应该被mutable来修饰,并且放在函数后后面关键字位置。

这里应该是函数用const修饰后,又想修改函数内的成员变量的值,那么该成员变量应被mutable修饰。
可以增加例子,便于理解,一部分人之前没见过这个关键字。

class person
{
int m_A;
mutable int m_B;//特殊变量 在常函数里值也可以被修改
public:
     void add() const//在函数里不可修改this指针指向的值 常量指针
     {
        m_A=10;//错误  不可修改值,this已经被修饰为常量指针
        m_B=20;//正确
     }
}

class person
{
int m_A;
mutable int m_B;//特殊变量 在常函数里值也可以被修改
}
int main()
{
const person p;//修饰常对象 不可修改类成员的值
p.m_A=10;//错误,被修饰了指针常量
p.m_B=200;//正确,特殊变量,修饰了mutable
}
例子来源:https://blog.csdn.net/qq_40776805/article/details/108422306

C++基础 第三条:构造函数能否声明为虚函数或者纯虚函数,析构函数呢?

原文:

构造函数不能定义为虚函数。在构造函数中可以调用虚函数,不过此时调用的是正在构造的类中的虚函数,而不是子类的虚函数,因为此时子类尚未构造好。

勘误:
根据《effective C++》的条款09:绝不在构造和析构过程中调用虚函数可知,在构造函数中虽然可以调用虚函数,但是强烈建议不要这样做。因为基类的构造的过程中,虚函数不能算作是虚函数。若构造函数中调用虚函数,可能会导致不确定行为的发生

40、什么情况下会调用拷贝构造函数(勘误)

示例代码中情况3,代码注释有提到NRV优化的情况,然后后面表述为

情况3在执行return时,理论的执行过程是:产生临时对象,调用拷贝构造函数把返回对象拷贝给临时对象,函数执行完先析构局部变量,再析构临时对象, 依然会调用拷贝构造函数

我在linux g++9.2版本情况下编写了一段测试程序,测得这种值返回函数的情况是不会调用其拷贝构造的,原因也就是NRV优化,但这个优化是跟随编译器及编译模式走的,以下是一篇我觉得讲得还算详尽的文章

理解NRV优化

13和68题,建议合并

68、成员列表初始化的使用情况?作用?

  1. 必须使用成员初始化的四种情况
    ① 当初始化一个引用成员时;
    ② 当初始化一个常量成员时;
    ③ 当调用一个基类的构造函数,而它拥有一组参数时;
    ④ 当调用一个成员类的构造函数,而它拥有一组参数时;
  2. 成员初始化列表做了什么
    ① 编译器会对初始化列表一一处理,以适当的顺序在构造函数之内安插初始化操作,并且在任何显示用户代码之前;
    ② list中的项目顺序是由类中的成员声明顺序决定的,不是由初始化列表的顺序决定的;

参考资料:《C++对象模型》P74

C++基础语法:“39、volatile、mutable和explicit关键字的用法”(补充)

补充位置:
image

补充内容:
用explicit关键字修饰类型转换运算符,即C++11新标准引入的显示的类型转换运算符。和显式的构造函数(用explicit修饰的单个参数的构造函数)一样,编译器(通常)不会将一个类型转换运算符用于隐式类型转换,避免引发意想不到的结果。

来源:
来源-C++ Primer 516页
A0MW(8STNCVKIFM{W)8MLH6

操作系统勘误

勘误@阿秀

11、动态分区分配算法有哪几种?可以分别说说吗?

PPT重叠了

14、一个程序从开始运行到结束的完整过程,你能说出来多少?

应该是一个程序从文本到可执行文件要经历哪些过程?

15、通过例子讲解逻辑地址转换为物理地址的基本过程

PPT重叠了

19、进程间通信有哪几种方式?把你知道的都说出来

失败范湖范围-1

41、Windows和Linux环境下内存分布情况

.bss段

57、可能是最全的页面置换算法总结了

建议加一下缓存置换算法,比如LFU。很多人,比如我,经常把LRU和LFU搞混。

59、死锁相关问题大总结,超全!

死锁应该是两个进程之间产生的。建议参考:https://baike.baidu.com/item/%E6%AD%BB%E9%94%81/2196938#2


建议

补充如下内容:

😀内存分配方式?

内存为程序分配空间有四种分配方式:

1、连续分配方式

2、基本分页存储管理方式

3、基本分段存储管理方式

4、段页式存储管理方式

😀什么是文件,文件描述符?

在Linux操作系统中,一切皆文件。为了将应用程序和文件对应,文件描述符应运而生。例如0表示标准输入,1表示标准输出,2表示标准错误。fd是非负整数。实际上它是一个索引值,指向内核为每个进程所维护的该进程打开的文件记录表。

😀你说一下缓存置换算法有哪些?

包括LRU, LFU, FIFO, ARC, MRU。

C++ 第106题

原文:如果数据对象是数组,则只能使用指针
反例:

template<typename T, int N>
void func(T (&a)[N])
{
    a[0] = 2;
}

int main()
{
    int a[] = { 1, 2, 3 };
    func(a);
    cout << a[0] << endl;
    return 0;
}

关于SSL/TLS的补充建议

在计网部分21题提到了SSL/TLS的四次握手,目前网上的主流答案都在重复阮一峰老师的博客,属于TLS 1.0版本的答案,使用RSA密钥交换算法。
但是现在TLS 1.2已经成为主流,使用ECDHE算法,如果面试可以说出这个版本的答案,应该会更好。

参考链接

SQL第33和35题

SQL第33题,聚族索引和聚合索引应该改成聚集索引。
SQL第35题,应该是聚集索引和非聚集索引

C++ 第120题

原文:char* strncpy(char* strDest, const char* strSrc, int pos)
strncpy的原型应该为:char *strncpy(char *dest, const char *src, size_t n)

勘误:操作系统第5节

5、进程线程模型你知道多少?
相关接口:int pthread_create(pthread_t pthread, const pthread_attr_t *attr, void *(start_routine)(void *), void *agr);第1、3个参数类型有误
应为:int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, void *(start_rtn)(void),void *arg);

stl的第9点勘误

第9点的“list是单向的, vector是双向的” 应该写反了吧。

网络第100题

关于 慢开始&拥塞避免那段
假设窗口长度为d,这应该不是收到一个确认就翻倍,应该是收到一个确认就加1,正好收到了d个确认,所以一共加d,正好是翻倍。
超时重传后是慢启动,慢启动是指数增加的,不是线性的。

I Need Your Help!

前言

如果你有不错的互联网大厂面试经历,社招、校招均可,类似这种 校招社招分享集锦

如果你对某一个 C++ 知识点有过深刻的见解和记录(暂不接受Java、Python、Go类稿件)

如果你有什么学习编程的经验分享给其他人

如果你对某一个计算机基础知识有自己的理解

......
你都可以把这些整理成文章投稿给我,你的文章将被更多人看到,你所写的东西也
可能会默默影响到很多人。
希望你的文章字数在1500+,图文并茂。

奖励

投稿自己的原创文章成功之后不仅可以顺利加入阿秀的 CS 开源项目 InterviewGuide: https://github.com/forthespada/InterviewGuide 扩大自己的竞争力,还会有100-300元的奖励(根据具体文章来判别)。

投稿方式

1、直接联系我

如果你有我的微信的话,你可以直接私信我投稿;没有的话可以扫描该二维码联系我

2、将你的文章以 Markdown 格式发送到我的邮箱: [email protected],希望您留下联系方式(电话号码或者微信号),我会主动与您取得联系

C++基础语法:“39、volatile、mutable和explicit关键字的用法”(勘误)

错误位置:
image

错误原因:
Mutable是用来修饰类的成员变量的,而不是修饰成员函数的。

来源和代码验证:
来源-C++ Primer 245页
image

代码验证-加在函数的参数列表后大括号前面会报错
image

我认为划红线的地方应该改为:
那么这个成员变量应该被mutable来修饰,mutable关键字在成员变量声明的时候加在最前方。

39题内容整理

39题部分知识点重复,以下是重新整理内容。
39、内联函数和宏定义的区别
主要区别
• 宏在预编译时进行,只做简单字符串替换。
• 内联函数在编译时直接将函数代码嵌入到目标代码中,省去函数调用的开销来提高执行效率,并且进行参数类型检查,具有返回值,可以实现重载。
内联函数适用场景
• 使用宏定义的地方都可以使用inline函数。
• 作为类成员接口函数来读写类的私有成员或者保护成员,会提高效率。
为什么不能把所有的函数写成内联函数
• 函数体内的代码比较长,将导致内存消耗大。
• 函数体内有循环,函数执行时间要比函数调用开销大。

InterviewGuide 勘误

错误题目,C++第 96 题 -- 智能指针的循环引用
原例子:

#include <iostream>
using namespace std;

template <typename T>
class Node
{
public:
	Node(const T& value)
		:_pPre(NULL)
		, _pNext(NULL)
		, _value(value)
	{
		cout << "Node()" << endl;
	}
	~Node()
	{
		cout << "~Node()" << endl;
		cout << "this:" << this << endl;
	}

	shared_ptr<Node<T>> _pPre;
	shared_ptr<Node<T>> _pNext;
	T _value;
};

void Funtest()
{
	shared_ptr<Node<int>> sp1(new Node<int>(1));
	shared_ptr<Node<int>> sp2(new Node<int>(2));

	cout << "sp1.use_count:" << sp1.use_count() << endl;
	cout << "sp2.use_count:" << sp2.use_count() << endl;

	sp1->_pNext = sp2; //sp1的引用+1
	sp2->_pPre = sp1; //sp2的引用+1

	cout << "sp1.use_count:" << sp1.use_count() << endl;
	cout << "sp2.use_count:" << sp2.use_count() << endl;
}
int main()
{
	Funtest();
	system("pause");
	return 0;
}
//输出结果
//Node()
//Node()
//sp1.use_count:1
//sp2.use_count:1
//sp1.use_count:2
//sp2.use_count:2

其中对Next和Pre赋值处的注释有问题,正确为:

    sp1->_pNext = sp2; //sp2的引用+1
    sp2->_pPre = sp1; //sp1的引用+1

C++基础:”37、public、protected 和 private 访问和继承权限/public/protected/private的区别?“(补充理解)

一、访问权限

访问权限 外部 派生类 内部
public
protected
private

public、protected、private 的访问权限范围关系:

public > protected > private

二、继承权限

  1. 派生类继承自基类的成员权限有四种状态:public、protected、private、不可见

  2. 派生类对基类成员的访问权限取决于两点:一、继承方式;二、基类成员在基类中的访问权限

  3. 派生类对基类成员的访问权限是取以上两点中的更小的访问范围(除了 private 的继承方式遇到 private 成员是不可见外)。例如:

  • public 继承 + private 成员 => private

  • private 继承 + protected 成员 => private

  • private 继承 + private 成员 => 不可见

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.