DAY03

今天又过了一遍面试题

首先是const和define的区别,define是在编译时进行替换。说到编译又能联想到生成可执行程序的步骤,首先是预编译,就是将define,inline,include中的定义的变量用代码进行替换。编译是将预处理后的文件转换成汇编代码。汇编是生成.o文件,链接将多个.o文件和库文件链接到一起生成.exe文件。而const是在运行的时候起作用。除此之外,define是没有数据类型的,然后const是有数据类型的。以及define定义的常量是不会分配内存空间的,而const定义的常量会分配到常量分配区。说到文字常量区,昨天忘记把内存布局写上了,栈,堆,全局静态区,文字常量区,程序代码区。

其次是get了虚函数表的一个小细节,虚函数表是一个指针数组,该指针指向每个对象的虚函数入口地址。

类型转换,static_cast 再常量类型间相互转换,int到float之类的。而dynamic_cast是在基类和派生类之间,向上转型是安全的,即派生类转型为基类指针,因为派生类会继承基类的虚函数表,而向下转型是危险的,因为基类对象的内存布局也不包含派生类对象呀。

接着就是c++模板,这个东西我也说不清楚,肯定是学艺不精,明天再稳固一下。

接着就是STL中的序列是容器和关联式容器,首先序列式容器会出现一个问题就是迭代器失效,观察源码会发现erase底层会将下一位的Newit返回,而当前it已经被释放掉了,即当前的it会指向空,再使用这个it会触发迭代器失效,避免失效只需要充值迭代器就好了。关联式无非是红黑树和哈希表,小数据用哈希,大数据红黑树。

迭代器和指针的区别:首先迭代器是一个类模板,重载了指针的一些操作符,迭代器返回的是对象的引用。迭代器可以检查越界和非法操作。指针不能检查。

又深度过度了一下智能指针和lambda,lambda创建一个类对象,这个类对象重载了函数访问运算符(),捕获列表[]将捕获到的变量初始化类对象的变量达到和函数调用一样的效果。

其次就是静态多态和动态多态,静态多态在编译期间就指定了调用哪个函数,动态多态基类指针指向派生类对象。

内存对齐:避免出现去内存中读两次甚至更多次才能将一个完整的数据读出的情况。

后面就是算法,二叉树的前序遍历,中序遍历,后序遍历,都是采用栈的形式,前序和后序差不多将根节点先入栈,然后调用一个while循环判断栈不为空,出栈,将该结点添加到vector中。然后对左右孩子,先后入栈,因为栈是先进后出所以先入右孩子,再入左孩子。返回vector即可。

后序遍历是先入左孩子再入右孩子,vector中存储的就是根右左了,再进行翻转变成左右根。

中序遍历有点复杂根节点不必先入栈,再while循环中加了两个判断(!stack.empty() || !cur),if(!cur)就会一直将左孩子入队,直到左孩子为空跳到else语句中将该结点的value添加到vector中,然后找它的右孩子,直到循环结束。

层次遍历说起来更符合人的思维,即用一个队列,将第一层的结点添加到队列,再while中先获取队列的长度,出队列将结点的左右孩子依次添加,第一层出队完毕,就到了第二层,依次往下。

然后又看到了几个有意思的面试题,互斥锁和自旋锁的区别,一个需要上下文切换,一个不需要,因为太晚了有些着急回去了,还有TCP和UDP以及函数重载的原理。明天再详细介绍。

说一下自己的感受,老是执着于看源码不仅提升不了自己,还会陷入短时间收获不到回报的焦虑。应该跟着别人一起学习源码的使用,然后用已知的经验来推演一个新的框架。就比如网络架构的recator,就能够借鉴他的事件和回调机制去学习skynet模型的actor的消息机制。这是一个很好的思路,希望我以此为戒,不能光靠看源码感动自己,和已有的旧知识建立关联才更能激发学习的兴趣。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值