面试
独L无二
一位颇为清高的女程序媛
展开
-
二分查找非递归
public static int binary(int[] arr, int data) { int min = 0; int max = arr.length - 1; int mid; while (min <= max) { // 防止溢出 mid = min + (max - min) / 2; if (arr[mid] > data.原创 2020-09-23 14:27:58 · 97 阅读 · 0 评论 -
学习算法推荐入门书籍
《我的第一本算法书》+《算法图解》https://www.cnblogs.com/wangmeng980/p/10325486.html原创 2019-06-03 11:35:40 · 3951 阅读 · 0 评论 -
2018 年力扣高频 算法面试题汇总
为啥我那么的后知后觉,现在才发觉有leetcode刷题一说?https://leetcode-cn.com/explore/interview/card/top-interview-quesitons-in-2018/原创 2019-08-19 15:53:50 · 831 阅读 · 0 评论 -
算法学习思维导图收藏
原创 2019-08-19 15:55:11 · 509 阅读 · 0 评论 -
数组指针和指针数组的区别
数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]p++; //该语句执行过后,也就...转载 2020-09-22 15:53:56 · 369 阅读 · 0 评论 -
智能指针源码解析
从源码理解智能指针(一)——auto_ptr、unique_ptr从源码理解智能指针(二)—— shared_ptr、weak_ptr转载 2020-09-17 09:43:31 · 1161 阅读 · 0 评论 -
不用中间变量交换两个变量的方法
面试中经常会出现的问题,主要针对整数类型,有两种解法:数值运算法void swap(int &A, int &B){ A = A + B; B = A - B; A = A - B;}从理解的角度来说,假如A'和B'代表交互以后的值,那么按照以上运算规则就有:A'=A+B; B'=A'-B=A+B-B=A; A'=A'-B'=A+B-A=B;最后运算的结果就变成了A'=B;B'=A;这样就完成了交换。异或运算法void swap(int &原创 2020-08-07 09:47:31 · 423 阅读 · 0 评论 -
侵入式容器 Boost.Intrusive
Boost.Intrusive 是一个很有意思的实现,里面实现了很多侵入式容器,在特定环境下,可以大大提升性能。首先我们得理解什么是侵入式,什么是非侵入式。普遍,我们认为std的容器,比如std::list都是非侵入式的。这是因为对于任何一个(支持复制或者移动的)类型T,我们都可以定义std::list<T>。当往std::list里插入一个元素时,它会分配一个节点,这个节点的结构类似于下面这个:struct Node { T data; Node* prev;转载 2020-09-13 20:29:54 · 2424 阅读 · 0 评论 -
C++ Performance Tips
C++ Performance TipsTable of ContentsIntroduction Constructors and Destructors Virtual Functions Return Value Temporaries InliningIntroductionThese tips are based mainly on ideas from the book Efficient C++ by Dov Bulka and David Mayhew. For a转载 2020-09-13 20:26:48 · 214 阅读 · 0 评论 -
C++的静态分发(CRTP)和动态分发(虚函数多态)的比较
虚函数是C++实现多态的工具,在运行时根据虚表决定调用合适的函数。这被称作动态分发。虚函数很好的实现了多态的要求,但是在运行时引入了一些开销,包括:对每一个虚函数的调用都需要额外的指针寻址 虚函数通常不能被inline,当虚函数都是小函数时会有比较大的性能损失 每个对象都需要有一个额外的指针指向虚表所以如果是一个对性能要求非常严格的场合,我们就需要用别的方式来实现分发,这就是今天这篇博客的主角CRTP。CRTP通过模板实现了静态分发,会带来很多性能的好处。可以参见The cost of dyn转载 2020-09-13 20:25:35 · 1216 阅读 · 0 评论 -
字符数组与字符指针的区别
1.字符指针可以指向一个字符串。 我们可以用字符串常量对字符指针进行初始化。例如,有说明语句:char *str = "This is a string.";是对字符指针进行初始化。此时,字符指针指向的是一个字符串常量的首地址,即指向字符串的首地址。这里要注意字符指针与字符数组之间的区别。例如,有说明语句:char string[ ]="This is a string.";此时,string是字符数组,它存放了一个字符串。字符指针str与字符数组string的区别是:str是.转载 2020-09-09 11:39:33 · 6429 阅读 · 2 评论 -
类成员变量可以是引用类型的么?
今天面试,面试官问我类的成员变量可以试引用类型的么?我回答yes。面试官:那怎么初始化呢?我:呃回来一试,确实可以,只不过不能用默认构造,必须带引用类型的构造函数完成初始化过程,而且一定要用初始化列表的形式完成初始化class Widget{public: // 构造函数形参为传值,不能保证正确性 //error: call to constructor of 'Ref' is ambiguous Widget (int target) :myref(tar原创 2020-09-01 19:29:43 · 2729 阅读 · 2 评论 -
Linux 信号signal处理机制
最近写程序,各种bug各种错,有一回程序莫名退出,没报错,也没产生日志和core文件,貌似正常退出一样。但又不是在程序全部走完后退出,中途莫名退出,这就叫我想到了signal,应该是某些函数错误后发送kill信号给主进程,然后退出。现在总结下signal各种类型: Signal Description SIGABRT 由调用abort函数产生,进程非正常退出 SIGALRM 用a.转载 2020-08-30 21:25:10 · 395 阅读 · 0 评论 -
C++异常机制
C++异常机制详解深入理解C++异常机制【C++】异常处理机制深度剖析原创 2020-08-28 20:56:34 · 124 阅读 · 0 评论 -
C++构造函数、析构函数与抛出异常么?
从语法上来说,构造函数和析构函数都可以抛出异常。但从逻辑上和风险控制上,构造函数可以,析构函数不推荐抛出异常。(1)构造函数可以抛出异常无论何时,从构造函数中抛出异常都是可以的。动态创建对象要进行两个操作:分配内存和调用构造函数。若在分配内存时出错,会抛出bad_alloc异常;若在调用构造函数初始化时出错,会不会存在内存泄漏呢?答案是不会。new运算符保证不会出现内存泄漏:T *p = new T;将被编译器转换给类似下面的样子: void allocate_and_cons.转载 2020-08-28 13:35:00 · 159 阅读 · 0 评论 -
STL vector,list,deque区别
在写C++程序的时候会发现STL是一个不错的东西,减少了代码量,使代码的复用率大大提高,减轻了程序猿的负担。还有一个就是容器,你会发现要是自己写一个链表、队列,或者是数组的时候,既要花时间还要操心怎么去维护,里面的指针啊,内存够不够用啊,长度问题,有没有可能溢出啊等等一系列的问题等着我们去解决,还是比较头疼的。所以容器的出现解决了这一个问题,它将这些数据结构都封装成了一个类,只需要加上头文件,我们就可以轻松的应用,不用那么复杂,就连指针也被封装成了迭代器,用起来更方便,更人性化,方便了我们的编程,对于程序员转载 2020-08-28 12:37:47 · 210 阅读 · 0 评论 -
C++常见面试题(转)
https://www.cnblogs.com/inception6-lxc/p/9244194.html原创 2020-08-28 12:35:07 · 91 阅读 · 0 评论 -
unorder_map的底层实现方法
哈希表哈希表是一个K_V的结构,,,,又被称为是散列表!!!!!它是根据关键字(key)来直接访问这个内存存储数据位置的数据结构;在构建哈希表的方法,我们这里主要介绍两种方法:1、直接地址法;什么意思呢?????就是直接取key(或者是某种线性函数)作为这个下表来存储数据 ,,,key在这里称作是 散列地址。。。可以理解成这个样子 Hash(Key)= Key 或Hash(Key)= A*Key + B,A、B为常数。。。。2、除留余数法;这里方法的说法是:就是..转载 2020-08-28 10:40:34 · 1577 阅读 · 0 评论 -
STL中map和set底层的红黑树实现
我们都知道map和set的实现是依赖红黑树的怎样写红黑树可以让map和set都可以使用呢?在这里我们定义了一个模版参数,如果它是key那么它就是set,如果它是map,那么它就是map;我们分析一下,红黑树迭代器的前置++到当前结点,就说明了它的左子树和自己都已经访问过了1,当前位置,若右树不为空,则访问右树的最左结点2,当前位置,若右树为空,则找祖先中孩子不是他的右若右访问完,那么父亲这棵树也就访问完了前置–的算法思想和++是近似的。比较大小时,set直接比较它的key,而map是比转载 2020-08-28 09:49:30 · 470 阅读 · 0 评论 -
C++11智能指针(unique_ptr、shared_ptr、weak_ptr)
很多人怕写C/C++ 程序就是因为指针,因为指针给了程序员高度的自由,同样也赋予了高度的责任,稍有不慎就导致内存泄漏。其实写C++ 可以完全不用指针,尤其C++ 11对智能指针作了进一步的升级,在不需要使用任何裸指针的前提下也可以写出高效的C++ 程序。C++ 11中定义了unique_ptr、shared_ptr与weak_ptr三种智能指针(smart pointer),都包含在<memory>头文件中。智能指针可以对动态分配的资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构转载 2020-08-27 16:21:38 · 366 阅读 · 0 评论 -
c++11 push_back与emplace_back之间的区别
使用empalce操作新标准中加入了三个新成员——emplace、emplace_front、emplace_back。这些是操作构造,而不是拷贝构造。这些操作分别对应以前的insert、push_front、push_back。允许我们将元素放置在一个指定位置之前或容器头部或容器尾部。当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理转载 2020-08-27 13:56:54 · 712 阅读 · 0 评论 -
auto_ptr Vs. unique_ptr
auto_ptr是用于C++11之前的智能指针。由于 auto_ptr 基于排他所有权模式:两个指针不能指向同一个资源,复制或赋值都会改变资源的所有权。auto_ptr 主要有两大问题:o复制和赋值会改变资源的所有权,不符合人的直觉。o在 STL 容器中无法使用auto_ptr ,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable)。unique_ptr特性o 拥有它所指向的对象o 无法进行复制构造,也无法进行复制赋值操作o 保存指向某个..转载 2020-08-27 12:40:32 · 359 阅读 · 0 评论 -
为什么不要在STL容器中存储 auto_ptr 对象?
大多数C++ 程序员都知道不要把auto_ptr 对象作为STL容器元素来使用。但是很少有人知道到底是为什么。C++标准如是说:“STL元素必须具备拷贝构造和可赋值……”,其意思是说对象可以进行安全的赋值操作,可以将一个对象拷贝到另一个对象,从而获得两个独立的,逻辑上相同的拷贝。尤其是当一个对象被拷贝到目标对象后,原来的对象不会改变。但 auto_ptr 却不然,用 auto_ptr 进行赋值和拷贝操作不仅会改变目标拷贝,而且还明显地改变原来的对象。明确地说,就是原来对象将指针的物主身份转换成目标对象,与此转载 2020-08-27 11:24:32 · 364 阅读 · 0 评论 -
死锁原因及解决方法
一、死锁的定义 多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。二、死锁产生的原因1)竞争不可抢占性资源 p1已经打开F1,想去打开F2,p2已经打开F2,想去打开F1,但是F1和F2都是不可抢占的,这是发生死锁。2)竞争可消耗资源引起死锁 进程间通信,如果顺序不当,会产生死锁,比如p1发消息m1给p2,p1...转载 2020-08-26 14:54:49 · 2844 阅读 · 1 评论 -
virtual 函数可以是private么?
答案是yes!这恰好是NVI的实现方式。。。什么是NVI?non-virtual interface(NVI):令用户通过public non-virtual成员函数间接调用private virtual函数,将这个non-virtual函数称为virtual函数的wrapper。wrapper确保得以在一个virtual函数被调用之前设定好适当场景,并在调用结束之后清理场景(也即是设计模式中的模版方法)。注意此时用指针或引用调用该non-virtual成员函数时,该non-virtual成员函原创 2020-08-22 21:30:04 · 1048 阅读 · 0 评论 -
STL List简单实现
原理:list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。优点:任意位置的插入删除效率很高(双向迭代)缺点:任意位置的随机访问效率很低#pragma once#include <iostream>#include <assert.h>//原生态指针:所存储元素类型的指针 例如 vector //将原生态指针进行封装template <class T>//结点定义stru.转载 2020-08-20 18:06:13 · 385 阅读 · 0 评论 -
STL中常用的算法
为了处理容器内的元素,STL提供了一些标准算法,包括查找、排序、拷贝、重新排序、修改、数值运算等基本而普遍的算法。算法并非容器内的成员函数,而是一种搭配迭代器使用的全局函数。这么做有一个重要的优势,所有算法只需要实现一份,就可以对所有容器运作,不必为每一种容器量身定做。1、非更易型算法2、更易型算法3、移除型算法4、变序型算法5、排序算法6、已排序区间算法7、数值算法1、非更易型算法 非更易型算法既不改动元素的次序,也不改动元素值。for_each() 对..转载 2020-08-20 17:53:55 · 387 阅读 · 0 评论 -
STL中vector的实现及面试问题
一、前言:在学习c++的时候我们会接触两个库,一个是boost库另外一个就是STL库。关于STL库候捷先生的《STL源码剖析》中已经写的很详细了,今天我就关于STL中的vector实现及面试中的一些与之相关的问题做一个讲解。在面试C++的时候关于vector是作为基础知识经常被问到的,如果面试官问你vector的实现原理,你会怎么回答呢?二、vector的实现原理及实现机制关于vector简单的讲就是一个动态增长的数组,里面有一个指针指向一片连续的内存空间,当空间装不下的时候会自动申请一片更大的空间(转载 2020-08-20 17:39:40 · 923 阅读 · 0 评论 -
C++ HashTable的简单实现
hashtable :本文中采用开链法( separate chaining )来处理 “ 冲突 ” ( collision ),而且 hashtable只存储唯一的元素,不存在重复。class hashtable {public: // 构造函数, n 为想要构造的 hashtable 的 bucket 数量 hashtable(size_t n); ~hashtable(); // 插入元素。若元素不存在,插入成功返回 true ;若元素已存在则插入失败,返回转载 2020-08-20 15:52:03 · 1126 阅读 · 0 评论 -
线程间的通信、同步方式与进程间通信方式
1、线程间的通信方式 使用全局变量 主要由于多个线程可能更改全局变量,因此全局变量最好声明为volatile 使用消息实现通信 在Windows程序设计中,每一个线程都可以拥有自己的消息队列(UI线程默认自带消息队列和消息循环,工作线程需要手动实现消息循环),因此可以采用消息进行线程间通信sendMessage,postMessage。1)定义消息#define WM_THREAD_SENDMSG=WM_USER+20; 2)添加消息函数声明afx_msg int OnTSendms转载 2020-08-14 18:19:50 · 839 阅读 · 0 评论 -
sizeof()大小总结
sizeof 运算符查询对象或类型的大小在需要知道对象的实际大小时使用语法:sizeof(类型) sizeof 表达式解释返回 类型 的对象表示的字节数。 返回当 表达式 求值时所返回的类型的对象表示的字节数。#include <iostream>class A{};int main(){ A a; std::cout<< sizeof a <<endl; //OK 1 //std::cout<< sizeo转载 2020-08-14 13:37:47 · 5333 阅读 · 1 评论 -
C++11常用新特性快速一览
最近工作中,遇到一些问题,使用C++11实现起来会更加方便,而线上的生产环境还不支持C++11,于是决定新年开工后,在组内把C++11推广开来,整理以下文档,方便自己查阅,也方便同事快速上手。(对于异步编程十分实用的Future/Promise以及智能指针等,将不做整理介绍,组内使用的框架已经支持并广泛使用了,用的是自己公司参考boost实现的版本)1. nullptrnullptr 出现的目的是为了替代 NULL。在某种意义上来说,传统 C++ 会把 NULL、0 视为同一种东西,这取决于编译转载 2020-08-14 12:57:38 · 134 阅读 · 0 评论 -
.lib和.dll的区别和使用
共有两种库:1.一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。2.一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。共有两种链接方式:1.动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。2.静态链接使用静态链接库,链接器从静态链接库转载 2020-08-14 12:35:41 · 343 阅读 · 0 评论 -
进程和线程的区别
进程一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。线程进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也转载 2020-08-14 09:20:24 · 1042 阅读 · 0 评论 -
面试中经常考到的MyString class的实现
头文件实现:#ifndef STRINGCLASS_MYNEWSTRING_H#define STRINGCLASS_MYNEWSTRING_H#include <iosfwd>class MyNewString {public: MyNewString(char* pData = nullptr); ~MyNewString(); MyNewString(const MyNewString& src); MyNewString&原创 2020-08-12 21:32:40 · 197 阅读 · 0 评论 -
虚函数和虚函数表
多态是由虚函数实现的,而虚函数主要是通过虚函数表(V-Table)来实现的。如果一个类中包含虚函数(virtual修饰的函数),那么这个类就会包含一张虚函数表,虚函数表存储的每一项是一个虚函数的地址。如下图:这个类的每一个对象都会包含一个虚指针(虚指针存在于对象实例地址的最前面,保证虚函数表有最高的性能),这个虚指针指向虚函数表。注:对象不包含虚函数表,只有虚指针,类才包含虚函数表,派生类会生成一个兼容基类的虚函数表。原始基类的虚函数表 下图是原始基类的对象,可以看到虚指针在地址的最转载 2020-08-12 18:01:07 · 1001 阅读 · 0 评论 -
mutable VS. volatile
1 mutable 在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。struct ST { int a; mutable int b; }; const ST st={1,2}; st.a=11; //编译错误 st.b=22; //允许 mutable在类转载 2020-08-11 14:59:27 · 83 阅读 · 0 评论 -
ASCII和Unicode编码的区别
https://blog.csdn.net/skh2015java/article/details/80500482归纳:编码 大小 支持语言 ASCII 1个字节 英文 Unicode 2个字节(生僻字4个) 所有语言 UTF-8 1-6个字节,英文字母1个字节,汉字3个字节,生僻字4-6个字节 所有语言 具体解释:最早...转载 2019-05-25 16:28:31 · 3029 阅读 · 0 评论 -
质因数分解算法C++实现
算法思想:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。(2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n, 重复执行第一步。(3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。#include "stdio.h"#incl...原创 2019-05-31 12:07:04 · 11301 阅读 · 0 评论 -
广度优先搜索(BFS)C++实现
算法思想:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,…,wi,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点;再从这些访问过的顶点出发,再访问它们所有未被访问过的邻接顶点……依次类推,直到图中所有顶点都被访问过为止。广度优先搜索是一种分层的查找过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况,因此它不是一个递归的算法...原创 2019-06-07 20:39:49 · 8610 阅读 · 1 评论