使用set
遍历插入set,当插入的时候返回false,就表明这个元素是重复的,那么就通过遍历查找,删除所有的这个元素,以此类推,得到剩下的元素就是不重复的
注意全部查找的方法:
while ((pos = src.find(s[i], pos)) != string::npos){std::cout << "pos = " << pos << std::endl;src.erase(pos, 1);pos++;}
9、 两个单链表是否相交
对于单链表问题,优先考虑将单链表变成循环链表
10、 扔玻璃球看在哪层楼会摔碎
既然第一步(确定临界段)的投掷数增加不可避免,我们就让第二步(确定临界层)的投掷数随着第一步的次数增加而减少。第一步的投掷数是一次一次增加的,那就让第二步的投掷数一次一次减少。假设第一次投掷的层数是f,转化成数学模型,就是要求f+(f-1)+…+2+1>=99,即f(f+1)/2>=99(第一次测试点选择100层是无意义的,必然会碎,所以无任何测试价值,所以第一次测试点k是1-99中的一个数),解出结果等于14。丢下第一颗鸡蛋的楼层就分别是 14 , 27 , 39 , 50 , 60 , 69 , 77 ,84 , 90 , 95 , 99 。
找到
int MaxSubSum(int arr[],int len)
{
int i;
int MaxSum = 0;
int ThisSum = 0;
for( i = 0;i < len; i++)
{
ThisSum += arr[i];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
/*如果累加和出现小于0的情况,
则和最大的子序列肯定不可能包含前面的元素,
这时将累加和置0,从下个元素重新开始累加 */
else if(ThisSum < 0)
ThisSum = 0;
}
return MaxSum;
二、 阿里巴巴(秋招 / 阿里云-边缘计算)
1、 5G知识
2、 MEC知识
3、 Vlan标签怎么打
4、 线程间通信方式
锁机制:包括互斥锁、条件变量、读写锁
互斥锁提供了以排他方式防止数据结构被并发修改的方法。
读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
5、 系统中断信号处理函数能不能被修改,其中如果有sleep函数会怎样?
三、 百度(秋招 / C++开发)
1、 Vector申请内存的方式
vector().swap(myvector);
reserve 是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用容器内的元素,因此当加入新的元素时,需要用 push_back()/insert() 函数。
2、 多线程实现广度优先遍历
3、 长连接短连接
HTTP 的长连接和短连接本质上是 TCP 长连接和短连接
HTTP 协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系。HTTP 是一个无状态的面向连接的协议,无状态不代表 HTTP 不能保持 TCP 连接,更不能代表 HTTP 使用的是 UDP 协议(无连接)。
在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次 HTTP 操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的 Web 页中包含有其他的 Web 资源(如 JavaScript 文件、图像文件、CSS 文件等),每遇到这样一个 Web 资源,浏览器就会重新建立一个 HTTP 会话。
而从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP 协议的长连接和短连接,实质上是 TCP协议的长连接和短连接。
4、 平衡二叉树及深度优先遍历和广度优先遍历
**二叉排序树(Binary Sort Tree)**又称二叉查找树。它或者是一棵空树;或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3)左、右子树也分别为二叉排序树
平衡二叉树定义(AVL,Adelson-Velskii and Landis):它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
(AVL)平衡二叉树是一种二叉排序树,其中每个结点的左子树和右子树的高度差至多等于1。它是一种高度平衡的二叉排序树。意思是说,要么它是一棵空树,要么它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
平衡二叉树是一种二叉排序树。也就是二叉排序树包含了平衡二叉排序树,其次它要满足后面的约束条件,就是每个结点的左子树和右子树的高度差不超过1
5、 手写代码:在一个数组中找出所有m个和为n的子数组。
6、 TCP/UDP各自的应用场景。
7、 手写代码:实现strcpy函数。
四、 字节跳动(提前批 / 客户端开发)
1、 http和https的区别是什么?
2、 手写代码:给定一系列区间,要求整合重叠区间,输出最终的区间情况。
五、 深信服(提前批 / C++开发(物联网方向))
1、 怎么解决内存泄漏问题?
-
valgrind
-
利用pmap+gdb,pmap可以列出特定进程的所有内存分配的地址和大小,通过gdb就可以直接看这些地址属于什么变量,通过统计这些内存地址的大小,就可以很容易的发现问题。利用自动化的gdb调试工具也可以很方便的定位。
-
利用一些trace工具,比如ptrace,strace之类的工具,这些trace工具会追踪特定的api,只需要统计malloc和free的调用次数就可以简单的发现是否有泄漏,但是无法定位代码行。
2、 new 和malloc在申请内存失败后会怎样
try{int *p = new int[10];}catch(std::bad_alloc){}
3、 防御性编程
-
通过采用良好的编程风格,来防范大多数编码错误
-
编码的目标是清晰,不只是简洁
-
检查所有的返回值
-
使用安全的数据结构
-
在声明的位置上初始化所有的变量
-
尽可能推迟一些声明变量
-
谨慎地进行强制转换
-
assert断言
4、 数组和链表的区别
不同:链表是链式的存储结构;数组是顺序的存储结构。
链表通过指针来连接元素与元素,数组则是把所有元素按次序依次存储。
链表的插入删除元素相对数组较为简单,不需要移动元素,且较为容易实现长度扩充,但是寻找某个元素较为困难;
数组寻找某个元素较为简单,但插入与删除比较复杂,由于最大长度需要再编程一开始时指定,故当达到最大长度时,扩充长度不如链表方便。
相同:两种结构均可实现数据的顺序存储,构造出来的模型呈线性结构。
5、 覆盖隐藏和重载
重载是指同名函数具有不同的参数表。
覆盖是指派生类中存在重新定义基类的函数,其函数名、参数列、返回值类型必须同父类中相应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体不同,当基类指针指向派生类对象,调用该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本。
隐藏是指派生类的函数屏蔽了与其同名的基类函数。
如果派生类的函数与基类的函数同名,但参数不同,则无论有无virtual关键字,基类的函数都被隐藏。
如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时基类的函数被隐藏。
6、 C++ 中使用 C 编译应该怎么调用
extern “C”{void foo(int x, int y); // 其它函数}
或者写成
extern “C”{#include “myheader.h” // 其它C 头文件}
这就告诉 C++ 编译译器,函数 foo 是个 C 连接,应该到库中找名字 _foo 而不是找 _foo_int_int。
C++ 编译器开发商已经对 C 标准库的头文件作了 extern“C” 处理,所以我们可以用 #include 直接引用这些头文件。
7、 gdb 调试的方法:如何在问题现场查问题
-
gdb 加入调试信息:-g
-
bt backtrace: 显示程序堆栈信息
8、 如何寻找最小的前十个数/找到无序数组中第k大的元素
- 【方法1】
维护一个大小为k的最小堆,遍历数组,如果数组元素比堆顶元素大,则用该元素替换堆顶元素。时间复杂度为O(nlogk).
- 【方法2】
用快速排序中分治的思想
取基准元素,将无序数组分为前后两段,前段所有元素的值小于等于基准,后段所有元素的值大于等于基准。记后段的长度为blen, 每次切分时,每次分治时,分3种情况讨论:
blen = k-1: 此时说明有k-1个数大于等于基准,基准就是第k大大数,直接返回基准
blen < k-1:此时说明第k大的数在前段,在前段中查找第(k-blen-1)大的数
blen > k-1:说明此时第k大的数在后段,在后段中查找第k大的数
此外还要注意类快排的分治法性能不稳定,分治的均匀性会影响算法的时间复杂度,分治越不均匀,算法效率越低。因此,当k=1或k=n时不要分治了,直接O(n)遍历数组求最大/最小值即可。这个优化可以大大提高效率。而最小堆解法性能稳定,不需要对k=1和k=n进行特殊处理。
9、 寻找两个字符串的最长公共子字符串
1) 穷举法
给定两个字符串 A 和 B,我们可以通过从 A 的第一个字符开始与 B 对应的每一个字符进行对比的方式找到最长的公共字串。如果此时没有找到匹的字母,则移动到 A 的第二个字符处,然后从 B 的第一个字符处进行对比,以此类推。
2) 动态规划-空间换时间
采用一个二维矩阵来记录中间结果,矩阵的横坐标为字符串1的各个字符,矩阵的纵坐标为字符串2的各个字符。
10、 malloc 最大能分配多大的内存,512M 的内存能够分配出这么多的空间吗
11、 简介二叉树,平衡二叉树存在的意义
12、 使用堆排序和使用快速排序有什么不同
13、 哈希表
14、 strcpy 的缺点
①:它是char *类型,它返回的是第一个参数的值,即一个字符的地址。
②:第一个参数不需要指向数组的开始。
如果想把一个字符串的一部分复制到另一个字符串的某个位置,该怎么办呢,显然strcpy()函数是满足不了这个功能的,strncpy()函数是为了弥补strcpy()函数不能检查目标字符串是否容纳下源字符串的不足而设定的一个函数。并且完全可以实现这个功能。
strcpy_s(szBuf, 2, “12131”); //新的CRT函数
strcpy(szBuf, “12131”); //老的CRT函数
上述代码,明显有缓冲区溢出的问题。使用strcpy_s函数则会抛出一个异常。而使用strcpy函数的结果则未定,因为它错误地改变了程序中其他部分的内存的数据,可能不会抛出异常但导致程序数据错误,也可能由于非法内存访问抛出异常。
使用新的增强安全的CRT函数有什么好处呢?简单地说,新的函数加强了对参数合法性的检查以及缓冲区边界的检查,如果发现错误,会返回errno或抛出异常。老版本的这些CRT函数则没有那么严格的检查与校验,如果错误地传输了参数或者缓冲区溢出,那么错误并不能被立刻发现,对于定位程序错误也带来更大困难。
六、 大疆(秋招 / 通信算法工程师)
1、 现在有一个无人机在飞,你手上有个遥控器,如果保障遥控器和无人机之间的可靠传输?
2、 WIFI频段和雷达频段之间的资源共享如何实现?
七、 京东(秋招 / 京东云-C++开发)
1、 手写代码:字符串单词逆序:“I like Beijing.”转成“Beijing. like I”
2、 32位操作系统和64位操作系统的本质区别。
3、 在完成三次握手后,如果网线被剪断,会发生什么?
4、 虚拟内存存在的必要性有哪些?
5、 进程间如何进行通信?
八、 华为(秋招 / 通用软件开发)
1、 手写代码:传入一个矩阵(n * n),将其翻转90°
2、 如何避免手机在wifi连接下切换AP带来的卡顿延迟问题?
九、 VIVO(秋招 / 嵌入式开发)
1、 int _p[5] 和int(_p)[5]的区别
2、 int arr[] = {1,2,3,4,5,6,7,8}
求*(&arr[1] + 7);
3、 简述大端问题小端问题
十、 OPPO(秋招 / 通信协议工程师)
4、 画出BACK的帧结构
5、 画出扫描-认证-关联的帧交互情况
6、 隐藏终端问题及其解决方法
7、 三种类型帧分别进行介绍
8、 帧聚合技术
9、 历数各代wifi协议的发展,要求细节到技术提升情况
10、 MIMO中使用的帧
十一、 TP_LINK(秋招 / 应用软件开发工程师)
1、 手写代码:找出两个单链表的第一个公共节点(要求使用至少两个方法)
2、 手写代码:一个只有数字0和1组成的数组,最大能有k个0替换成1的机会,请问该数组最长的全为1的子数组为多长?(询问算法复杂度及其优化方案)
3、 算法题:若干个非均匀的绳子,点燃后每根绳子可以燃烧1个小时,请设计算法,用最少的绳子找到15分钟的计时。
十二、 中兴(秋招 / 岗位1 软件开发)
1、 MIMO技术具体细节
2、 OFDMA技术具体细节
3、 5G的主流技术简介
4、 信道编码和信源编码的区别
5、 常见的信道编码方案
十三、 中兴(秋招 / 岗位2 通信讲师)
1、 试讲一下你所做的项目。
2、 给你三分钟时间,组织语言用英文表达你从进来到现在的所见所感。(然后面试官会用英语提问,要你回答)。
3、 讲一讲你最大的缺点
4、 讲一讲你是如何精进自己的授课能力的。
十四、 二十八所(秋招 / C++开发)
1、 算法题:有一个很大的数据存储在某个数据结构中,程序需要多次进行访问,要求每次的访问都是遍历,同时遍历的顺序每次都是随机的,请你设计方案,进行实现。
2、 智力题:为什么人在看镜子的时候是左右对称,而不是上下对称?
3、 如何消除多径干扰带来的影响?
4、 MIMO技术除了运用在wifi领域,还运用在哪些领域?
5、 vector的内存分配方式是什么?如何修改分配方式?
6、 哈希表简介
7、 信道编码都有哪些?
8、 星座图和眼图分别是用来干什么的?
9、 堆和栈有什么区别?
10、 常用的数字调制方式都有哪些?抗干扰性能最高的是哪个?为什么是这个?
11、 ISO七层模型详细描述,问各层的加密算法。
十五、 CVTE(提前批 / C++开发)
1、 malloc 和new的区别
(1)malloc与free是c++/c语言的标准函数,new/delete是C++的运算符。
(2)他们都可用于申请动态内存和释放内存。new/delete底层也是执行的malloc/free。new和delete在对象创建的时候自动执行构造函数,对象消亡之前会自动执行析构函数。
(3)new返回指定类型的指针,并且可以自动计算出所需要的大小。malloc必须用户指定大小,并且默然返回类型为void*,必须强行转换为实际类型的指针。
malloc实质:malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
2、 数组越界问题/内存泄漏问题
char s1[] = “aaaaaaaaaaaaaaa”;
char *s2 = “bbbbbbbbbbbbbbbbb”;
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
在计算机科学中,内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏与许多其他问题有着相似的症状,并且通常情况下只能由那些可以获得程序源代码的程序员才可以分析出来。然而,有不少人习惯于把任何不需要的内存使用的增加描述为内存泄漏,严格意义上来说这是不准确的。
一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,calloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。
3、 vector的实现方法
新增元素:vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数
据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。
删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。
删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。
4、 Win下的可执行程序和Linux下的可执行程序
(1)可执行的二进制文件包含了:机器指令、数据资源、程序运行资源(物理的和虚拟的内存空间、进程、线程资源等)。因此说明了,可执行文件执行之前,操作系统要做一些准备工作,根据不同的操作系统,准备工作是不同的,因此可执行文件的格式是不相同的。Windows下可执行文件格式为PE格式,linux下可执行文件为elf格式。所以说,文件格式的不同导致了可执行文件是不可以直接跨平台使用。
(2)由于不同的操作系统API(应用程序接口)不同,而一个可执行文件要执行时都需要操作系统的交互才能完成,而不同的操作系统交互操作的方法不同,因此不同操作系统下的可执行文件不能直接在对方那里直接运行。
5、 不同的操作系统是如何支持同一种语言的?
十六、 海康威视(秋招 / C++软件开发)
1、 手写代码:单例模式。
2、 手写代码:模板类。
3、 手写代码:如何兼用单例模式实现多种不同的单例取用(工厂模式)。
4、 手写代码:判断一棵树是不是平衡二叉树。
5、 手写代码:实现两个模块的函数回调。
6、 谈谈你对分布式系统的了解。
十七、 烽火通信(秋招 / 软开)
1、 (项目相关,无其他基础知识)
十八、 小米(秋招 / 系统开发工程师)
1、 TCP三次握手是什么,请详细说出每次握手对应的状态情况。
2、 手写代码:实现字符串中的单词逆序输出(如:“I love Beijing.”逆序输出为“Beijing. love I”)。
3、 Linux操作系统如何用命令查看当前系统使用的编码方式?
十九、 七二二所
1、 (项目相关,无其他基础知识)
二十、 七〇九所
1、 (项目相关,无其他基础知识)
二十一、 浦发银行(秋招 / 信息科技岗)
1、 异步和同步、阻塞和非阻塞的区别。
2、 长连接和短连接的区别,举例长连接和短连接的使用场景。
3、 什么是平衡二叉树,简述深度优先遍历。
二十二、 网易互娱(秋招 / 初级游戏开发)
1、 手写代码:将int型整数逆序输出另一个整数,如12345输出54321(不能使用string)
2、 手写代码:从任意M个数中随机取出N个不同的数。
3、 进程和线程共享的东西都有哪些?
4、 一个空类,一般都默认有哪些函数?
5、 拷贝构造函数会在哪些情况下被调用?
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
进阶学习视频
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
无其他基础知识)
二十一、 浦发银行(秋招 / 信息科技岗)
1、 异步和同步、阻塞和非阻塞的区别。
2、 长连接和短连接的区别,举例长连接和短连接的使用场景。
3、 什么是平衡二叉树,简述深度优先遍历。
二十二、 网易互娱(秋招 / 初级游戏开发)
1、 手写代码:将int型整数逆序输出另一个整数,如12345输出54321(不能使用string)
2、 手写代码:从任意M个数中随机取出N个不同的数。
3、 进程和线程共享的东西都有哪些?
4、 一个空类,一般都默认有哪些函数?
5、 拷贝构造函数会在哪些情况下被调用?
尾声
最后,我再重复一次,如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。
对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
进阶学习视频
[外链图片转存中…(img-6tlrZsKS-1716043414695)]
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-7tBITYIq-1716043414696)]