C++规范库的map和set有什么区别,如何实现的?

  • map和set都是C++的关联容器,其底层实现都是红黑树。
  • map和set区别在于:

    • map中的元素是key-value(键-值)对:关键字起到索引的作用,值则示意与索引相关联的数据;set是关键字的简略汇合,set中的元素都只蕴含一个关键字。
    • set的迭代器是const的,不容许批改元素的值;map容许批改value,但不容许批改key。
    其起因是map和set是依据关键字排序来保障其有序性的,如果容许批改关键字的话,那么首先须要删除该键,而后调节树均衡,再插入批改后的键值,再从新调节树均衡。这样会毁坏map和set的构造,导致迭代器生效。
    • map反对下标操作,set不反对下标操作。

map底层为什么要用红黑树实现?

  • 红黑树的特点:红黑树是二叉查找树,但在每个节点减少一个存储为示意节点的色彩,能够是红色或彩色,通过对任意一条从根到叶子的门路上各个节点着色形式的限度,红黑树确保没有一条门路会比其余门路长两倍。因而,它是一种弱均衡二叉树,绝对于严格的均衡二叉(AVL)树来说,它的旋转次数少,所以对于查找、插入、删除较多的状况下,通常应用红黑树。
  • AVL是严格均衡的,频繁的插入和删除,会引起频繁的再均衡,导致效率升高;红黑树是弱均衡的,算是一种折中,插入最多旋转2次,删除最多旋转3次。所以红黑树在查找、插入、删除的复杂度都是O(logn),且性能稳固,所以STL外面很多构造包含map底层都是应用的红黑树。

简述weak_ptr的作用

  • weak_ptr是为了配合shared_ptr而引入的一种智能指针,因为没有重载operator*和->,所以它不能像一般指针那样应用。
  • weak_ptr最大作用在于帮助shared_ptr工作,像旁观者那样观测资源的应用状况。weak_ptr能够从一个shared_ptr或者另一个weak_ptr对象结构,取得资源的观测权。但weak_ptr没有共享资源,它的结构不会引起shared_ptr援用计数的减少。
  • 应用weak_ptr的成员函数use_count()能够观测资源的援用计数,另一个成员函数expired()的性能等价于use_count()==0,示意被观测的资源曾经不存在。weak_ptr也能够应用成员函数lock()从被观测的shared_ptr取得一个可用的shared_ptr对象, 从而操作资源。但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。
  • 简略来说就是:

    • 观测shared_ptr资源应用状况。
    • 解除shared_ptr循环援用问题.

C/C++的参数入栈程序为什么是从右向左?

  • 从右向左压栈的程序是与C/C++反对可变参数无关的。C/C++要求在申明参数可变的函数时,须要有至多一个确定的参数。为什么呢?因为须要有一个参数为函数提供可变参数的类型(否则函数怎么晓得如何解析后续的可变参数?比方,可变参数列表中有两个参数,一个int型,一个byte型,函数在解析可变参数表时,怎么晓得这5字节的数据到底应该如何去解析)如果一个可变参数的参数类型当时确定的话,这个参数就没有存在的意义了。
  • 如果参数入栈程序是从左向右压栈,第一个参数(即形容可变参数表各变量类型的那个参数)将被放在栈底,因为可变参的函数第一步就须要解析可变参数表的各参数类型,即第一步就须要失去上述参数,因而,将它放在栈底是很不不便的。当然,从左向右压栈的话也能够实现可变参的性能,然而这样的话,该性能实现起来会简单些。

个别程序的虚拟内存空间为什么是4g?

  • 因为寻址空间取决于cpu地址线条数,如32位机,寻址空间为2^32 = 4G,所以最大只反对4G的寻址空间,即便插了8G的内存条也只能应用4G内存。

Duilib为什么绘图性能不好?

  • (答案仅供参考)Duilib是DirectUI思维的一种实现。DirectUI艰深来说就是在窗口上指定一块区域(仅仅是一个区域,不是一个实体控件)通过各种音讯模仿一个控件的性能。齐全能够在一个对话框类的OnMouseMove、OnLButtonDown等函数中模仿一个按钮进去。然而模仿的控件一多就凌乱了,为了对立治理,逻辑上更清晰相似于实体控件。把每种控件封装成类解决各种音讯,并通过自定义的音讯散发机制把音讯散发到各个模仿控件里。这种模仿的形式绘制和音讯解决效率相比于实体控件要低。
  • Duilib的图片绘制代码中也有影响性能的中央,所有的控件的图片绘制都是调用CControlUI的DrawImage函数,而此函数调用了CRenderEngine的DrawImageString函数。在绘制图片时,DrawImageString会解析图片字符串的属性,而后找到对片的HBITMAP资源,最初调用真正的绘图函数去绘制。问题就在于每绘制一个图片都会再次解析一次字符串,当界面比较复杂,而且图片字符串也比较复杂时,这个解析的过程就影响了程序效率。当然这能够通过缓存图片资源解析后果的形式来优化。

什么是内存泄露?如何查看内存泄露?

  • 内存透露是指在程序中动静申请的内存或者资源在应用完后,没有开释。这样可能导致程序应用的内存一直增大,最终会因零碎内存不足,而导致程序解体或其余谬误。
  • 在Windows下能够通过工作管理器查看内存应用状况,能够简略剖析是否有内存透露。也有很多像VLD这样的内存透露检测工具。如果是应用VC库来写程序的话,在Debug版本中也能够应用VC的C运行库中提供的像_CrtCheckMemory、_CrtCheckMemory、_CrtMemCheckpoint、_CrtMemDifference、_CrtMemDumpAllObjectsSince等函数来检测和定位内存透露问题。

C++程序解体的个别起因是什么?怎么定位解体问题?

  • 程序解体个别有3个起因:

    • 操作了野指针
    • 内存拜访谬误(包含格式化数据类型谬误、索引越界等)
    • 堆栈溢出
  • 在Windows下咱们个别会在编译程序时保留其pdb文件,设置解体时生成dump文件。因而,能够通过VS或者Windbg联合pdb文件来剖析解体产生的dump。大部分时候,通过Windbg的“!analyze -v”命令咱们就能定位到解体问题的代码行。如果解体的代码行不是理论引起问题的中央,咱们也能够通过相干代码的上下文联合log以及解体前操作等景象来剖析解体起因。最初,还能够通过dump查看解体时其余的堆栈或者线程信息,做进一步剖析。