C++ 虚函数实现?(小红书)

如果有100层继承关系,访问虚函数需要跳转几次?(小红书)

delete this 合法吗?(小红书)

new和malloc区别

malloc底层怎么实现的

编译链接过程

a.cpp里面我写了一个全局变量,b.cpp可以看到它吗,b里我定义了一个同名的全局变量会报错吗?什么时候报错?怎么样隐藏static变量呢?加上inline会怎么样呢?

一亿数据插入查找,unordered_map和map怎么选?(快手)

如需要顺序,有序输出,选择map。如需要保证插入查找性能,选择unordered map。

讲讲智能指针(金山办公)page 11

std::unique_ptr。独占所有权,禁止复制,只能通过move转移。

std::shared_ptr。共享,用内部引用计数管理生命周期。有循环引用问题,线程不安全。

std::weak_ptr。解决循环引用问题,不增加引用计数。用lock方法将weak ptr转为shared ptr。

讲讲gdb gcc(金山办公)page 11

gcc是编译套件,经预处理、编译、汇编、链接生成执行文件。参数如-g加调试信息,-O控制优化级别。

gdb是gnu开发的调试工具,可设置断点,用step进入函数内部,next跳过函数调用,backtrace查看调用栈。

段错误时可以用gdb加载core文件。

GDB调试切换线程用什么命令?(得物)

gcc如何预处理(金山办公)

gcc编译过程第一步是调用预处理器,include,define,条件编译等步骤。-E可以看预处理后的代码。

gcc如何获取不进行链接的代码(金山办公)

-c可以编译代码不链接,-S可以看汇编的代码。

C++线程安全的单例模式怎么实现(金山办公)page 10

单例模板类。用局部静态变量初始化。

std call_once。用call_once和once_flag。std::call_once 保证了多线程环境下只会执行一次初始化代码。

docker如何建立目录映射(金山办公)page 10

用docker run时,用-v指定映射关系。

top如何根据内存占用排序(金山办公)page 10

按M键,也可以用-o %MEM。

如何查找进程的句柄(金山办公)page 10

Windows,Sysinternals 的 Handle 工具。Linux,用命令 ls -l /proc//fd 可以列出具体文件或资源的链接。

查看进程端口占用(金山办公)page 10

netstat -anp | grep

查看进程打开的文件句柄(金山办公)page 10

lsof -p

说说git rebase(金山办公)page 10

重新构造分支提交历史。将一个分支上提交重放到另一个分支的最新提交后面。

rebase会找到当前分支和目标分支共同祖先,提取整理当前分支自那个祖先以来所有提交,把这些提交放到目标分支最新提交后。

和merge区别。merge会创建一个合并提交,保留两个分支的结构。rebase会删掉分叉记录。

git 如何创建分支(金山办公)page 10

git checkout -b。

说说经常使用的c++容器(金山办公)page 10

vector。底层实现是动态数组。

deque。双端队列。

list。基于双向链表实现。

map。基于红黑树实现。

unordered map。基于哈希表实现。

C++有哪些多线程库(金山办公)page 10

std::thread。启动线程和管理线程。std::mutex实现同步。std::atomic。实现原子操作。

pthread提供了posix跨平台多线程接口。

boost thread也是线程库。

C++ sort()使用了哪种排序算法(金山办公)page 8

用的是内省排序,是混合排序算法,结合了快速排序、堆排序、插入排序。

weak_ptr可以提升为shared_ptr吗?(金山办公)page 8

可以。调用lock方法。但前提是对象仍存在,否则返回空指针。

野指针与悬挂指针的区别(金山办公)page 8

野指针是指针存储的是不可知的随机的内存地址。悬挂指针是他曾经指向合法地址,但该地址释放,指针仍然指向原地址。

有一大堆重复int值,获知不同int的数量,用位图需要提前分配足量内存,假如这些值很稀疏,那就会浪费大量内存,怎么改进?(位图或布隆过滤器值很稀疏,怎么改进内存浪费?)(金山办公)page 8

分块位图。将整个 int 值的范围分成多个块。对于每个块,只在存在数据时才分配对应的位图,当某个块内没有数据时则不分配内存。

C++迭代器失效有哪几种情形?(金山办公)page 8

内存重分配。容量不够会内存重分配,原迭代器失效。

元素插入。vector在中间位置insert,后面的迭代器失效。

元素删除同理。

为什么拷贝构造函数的参数要使用引用传递?(金山办公)page 7

避免递归调用拷贝构造函数。避免数据拷贝。

C++的四种类型转换说一下?(金山办公)page 7

static_cast编译时类型转换,用于常规类型转换,int,指针,引用。

dynamic_cast用于继承转换,进行类型检查,转换失败返回nullptr。

reinterpret_cast用于位级别转换,直接操作内存。

const_cast去除或增加const或volatile。

从派生类转换为基类是否可以用static_cast?(金山办公)page 7

可以。

两个线程,同时对一个变量做100次加法,可能的最小值是?(金山办公)page 7

可能的最小值是 100。

c++ vector的扩容怎么实现,为什么选择两倍?(金山办公)page 5

几何级数扩容2的指数。均摊常数时间复杂度vector 满了需要扩容时,会重新分配一块更大的连续内存,并将原有元素复制过去。虽然单次扩容会涉及大量复制操作,但由于容量是呈指数级增长(例如每次扩容为原来的 2 倍),这种复制操作的成本可以被后续大量的插入操作“摊销”。

c++程序入口,入口前会执行什么内容(讲讲C++程序启动流程)(金山办公)page 7

操作系统加载可执行文件。将代码数据各个段映射到内存。

运行时库初始化代码。start函数初始化栈堆。初始化静态变量,全局对象。

加载动态链接库。

调用main。

c++一个线程1在读文件,主线程退出了,怎么让线程1也退出不继续读(金山办公)page 6

让线程协作退出,也就是采用协作式取消的方式。在线程1中,引入一个共享的标志变量(通常用 std::atomic),在读取循环中定期检查这个变量的状态。当主线程需要退出时,将该标志设置为 true。

Qt信号槽类型(金山办公)page 6

直接连接、队列连接、自动连接、阻塞队列连接。

c++面向对象中,类的static成员生命周期?(金山办公)page 6

static 成员在程序加载时(在 main 函数执行前)被分配内存,并在程序退出时才释放。

c++在编译时编译器对模板做了什么?(金山办公)page 6

模板定义的解析与检查。

模板实例化。实际使用时,编译器才会进行实例化。

C++多态,有哪些实现多态的方式(金山办公)page 6

运行时多态。虚函数(virtual)以及继承和基类指针(或引用)。基类中声明虚函数:在基类中将希望在派生类中进行重写的函数声明为 virtual。 派生类中重写虚函数:在派生类中对父类的虚函数进行重写,实现不同的行为。 基类指针或引用指向派生类对象:在运行时根据实际指向的对象调用相应的函数实现,这就是动态绑定的过程。

编译时多态。模板。编译时进行类型替换。函数重载和运算符重载。

c++ 结构体、类区别(金山办公)page 5

struct: 默认所有成员(包括数据成员和成员函数)的访问权限为 public。class: 默认所有成员的访问权限为 private。

struct: 在使用 struct 进行继承时,默认的继承方式为 public 继承。class: 使用 class 进行继承时,默认的继承方式为 private 继承。

c++ lambda捕获指针,指针可能失效,如何解决(金山办公)page 5

用智能指针管理资源。std::shared_ptr 或 std::unique_ptr 可以让资源的生命周期与lambda绑定。

数据的副本。

c++11之前,如何禁用类的某些函数(金山办公)page 5

将函数声明为私有成员。

简单说一下c++ malloc和new的区别(金山办公)page 5

malloc 是 C 标准库的函数,只负责分配一块原始内存,不会调用对象的构造函数。

malloc 返回 void* 类型,需要进行类型转换。new 返回具体类型的指针。

当 malloc 分配内存失败时,会返回 NULL。当 new 分配内存失败时,默认会抛出 std::bad_alloc 异常。

说一下c++ const 指针和指针 const的区别?(金山办公)page 5

const 指针,通过ptr不能修改它所指向的对象的数据,但指针本身可以指向其他对象。

指针 const,指针自身的值(即内存地址)不可修改,但可以通过它修改该地址所指向的数据。

有一个c++接口,是对那个文件进行操作,接口实现里有文件加锁和解锁操作。假设这个函数里面有很多的return,怎么能保证他return返回的时候成功解锁?(金山办公)page 5

用 RAII(资源获取即初始化)机制。将文件加锁操作封装在一个类中,在该类的构造函数中进行加锁,在析构函数中进行解锁。

c++中map和unordered_map的区别,底层实现(金山办公)page 5

map 用红黑树实现,有序,log n时间复杂度。unordered_map用哈希表实现,无序,O 1时间复杂度。

c++动态库和静态库的区别(金山办公)page 5

静态库在编译链接时嵌入可执行文件中。动态库在运行时由OS动态链接器加载。

如何从大量爬取的文章中去掉重复或高度相似的内容,只统计独特的文章数量?(金山办公)page 1

用模糊匹配,如局部敏感哈希,将文章拆分成若干特征n gram,计算每个文本的minhash签名,用局部敏感哈希算法聚类相似文章。

你对设计模式怎么理解?(金山办公)page 1

是对软件开发中问题的解决方案的总结。

创建型模式。工厂模式、单例模式。

结构型模式。代理模式、装饰器模式。

行为型模式。策略模式、观察者模式。

对于C++指针的理解 (金山办公)page 1

指针是变量,值为另一个变量在内存的地址。用法有取地址和解引用,用new delete动态分配释放内存。智能指针更推荐用来管理动态分配内存。const有一些组合使用方法,const 指针,通过ptr不能修改它所指向的对象的数据,但指针本身可以指向其他对象。指针 const,指针自身的值(即内存地址)不可修改,但可以通过它修改该地址所指向的数据。有一些问题需要注意,野指针和悬空指针,野指针:指针未初始化或指向未知内存区域,悬空指针:指针指向的内存已经释放,但指针仍然存在。

c++ vector和list的区别,使用场景(金山办公)page 1

底层数据结构。vector连续内存存储,元素数量超过容量时,vector重新分配内存,扩容2倍,或者按扩容因子扩容。list用双向链表实现。

场景。vector用于数组、矩阵。list用于如任务调度器任务队列、LRU缓存链表。

讲讲c++单继承后内存布局 ,多继承后内存布局 ,如何进行类型转换(金山办公)page 1

单继承,一个派生类只继承一个基类,将基类嵌入派生类对象最前面,内存包含虚表指针、基类、派生类数据成员。如果基类和派生类都有虚函数,虚函数表的更新也是按照声明顺序排列的。

多继承,内存包含基类1到n,最后是派生类自己的成员。如果将派生类类转化为基类1,因为地址是一样的,指针不变,如果转化为基类2,编译器转换时加偏移量。

虚继承,解决菱形继承,虚基类只有一个拷贝,且内存位置不固定,编译器在对象中加一个虚基指针,维护虚基表,保存虚基类偏移量。

类型转换。1.static_cast,根据编译时期获得的固定偏移量对指针进行调整。不进行运行时类型检查。2.dynamic_cast,用运行时类型信息检查指针实际指向的对象类型。如果转换不安全,返回nullptr或bad_cast。3.reinterpret_cast用于位级别转换,直接操作内存。4.const_cast去除或增加const或volatile。

讲讲C++程序编译流程(金山办公)page 1

预处理,宏替换和条件编译进行文本替换。

编译。1.词法分析,语法分析。将代码转化为token,构建语法树。2.中间表示。编译器生成中间表示,进行常量折叠,死代码消除,内联展开。然后将中间表示转为目标平台汇编代码。3.汇编。汇编器生成二进制目标文件。4.链接。将目标文件合并成一个可执行文件。进行符号解析,重定位和库函数链接。

讲讲C++多线程编程需要注意些什么内容(金山办公)page 1

线程安全。多线程共享数据,用std mutex,std lock guard,std unique lock,也可以用原子操作std atomic。

同步机制。std condition variable。

可见性。用volatile保证变量更新对其他线程可见。

聊聊观察者模式(金山办公)page 1

用于事件驱动编程,定义了对象一对多依赖关系,当主题对象变化时,他的观察者自动收到通知。

实现。主题维护观察者集合,用list保存。当主题状态变化时,调用notify Observers方法,遍历观察者列表,调用每个观察者的update方法。

讲讲extern关键字,static关键字(金山办公)page 1

extern声明一个变量或函数在其他文件定义。extern “C”是在c++中调用C接口。

static用在局部变量、全局变量和函数。static全局变量和函数只在当前文件可见。static局部变量的生命周期是整个程序,且只被初始化一次,保留上次状态。

C++如何解决循环引用的问题(金山办公)page 1

用 std::shared_ptr 和 std::weak_ptr 。将其中一个方向的引用声明为 std::weak_ptr 来打破强引用循环。

讲讲unique_ptr和shared_ptr的使用场景(金山办公)page 1

unique_ptr同一时间只有一个指针指向资源,不可拷贝,可以move,用于工厂创建资源后,把所有权给调用者。

shared_ptr比如观察者模式,回调机制用shared_ptr,循环引用用weak_ptr解决。

讲讲linux的内存布局(金山办公)page 1

用户空间、内核空间。1.进程有自己独立虚拟地址空间,存代码、数据、堆、栈。代码段只读,数据段存全局变量和静态变量,堆存动态分配的,如malloc,new,栈存储函数调用局部变量,返回地址。2.内核空间由操作系统使用,管理内核线程。3.虚拟内存管理。用分页和页表,将虚拟地址映射到物理内存。

C++运行出现Core Dump怎么办?(得物)