各厂面试经历

目录

** 动态库与静态库的区别

**  gcc如何加载动态库、静态库

**  数据库查询优化方法

** Linux下进程内存分段以及分别存储什么

** vector如何扩展内存和释放内存

** 浏览器访问vivo.com的过程

** 简单说下多线程(常用函数和锁说下)

** 定义一个数据结构保证多个线程读写的线程安全。

** 冒泡算法的优化

** 大量数据读写,数据的修改尽量不影响读和查询

** 内存泄漏是怎么引起的?怎么检查内存泄漏?

** 内存溢出

** 野指针

** 宏定义max(a,b)

** MySQL的引擎有哪些?

** SQL查询语句,不用肉眼观察,怎么知道用了什么索引?

** C++11标准有什么改进,std::Move是什么?

** 54张牌,一半黑一半白,拿出红的再拿出黑的的概率

 

 


一、vivo

(1)面试题

** 动态库与静态库的区别

  1. 静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。
  2. 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
  3. 动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。如果在当前工程中有多处对dll文件中同一个函数的调用,那么执行时,这个函数只会留下一份拷贝。但是如果有多处对lib文件中同一个函数的调用,那么执行时,该函数将在当前程序的执行空间里留下多份拷贝,而且是一处调用就产生一份拷贝。

**  gcc如何加载动态库、静态库

Linux 下的库文件分为两大类分别是动态链接库(通常以.so 结尾)和静态链接库(通常以.a 结尾),两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的 。默认情况下,GCC 在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static 选项,强制使用静态链接库。

**  数据库查询优化方法

  1. 通过建立索引对查询进行优化。
  2. 对查询进行优化,应尽量避免全表扫描

** Linux下进程内存分段以及分别存储什么

  1. 代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存种的镜像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。
  2. 数据段:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。
  3. BSS段:BSS段包含了程序中未初始化全局变量,在内存中bss段全部置零。
  4. 堆(heap):堆是用于存放进程运行中被动态分配的内存段,它大小并不固定,可动态扩张或缩减。当进程调用malloc/new等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
  5. 栈:栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味这在数据段中存放变量)。除此以外在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也回被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上将我们可以把堆栈看成一个临时数据寄存、交换的内存区。

** vector如何扩展内存和释放内存

vector使用一个数组实现的,有三个迭代器start、finish、end_of_storage。可用容量、已用容量。

  1. 实际容量不够时,重新配置1.5倍或者2倍的空间——元素移动——释放原空间
  2. 删除元素时,仅仅调用元素的析构函数,并不真正释放内存
  3. 可以用resize()改变大小。

** 浏览器访问vivo.com的过程

(1)获取vivo.com的IP地址。

  1. 查询操作系统和浏览器的缓存。
  2. 操作系统生成DNS请求报文,放置在53号目的端口的UDP报文段中,该UDP报文放入IP目的地址为DNS服务器的地址的IP数据报中。
  3. IP数据报——以太网帧——网关路由器(IP地址由ARP查询报文、广播获得)——转发表(RIP、OSPF、BGP)——DNS服务器——查找缓存(依此查询根服务器、顶级服务器、权威服务器)——DNS回答报文。

(2)建立TCP链接

  1. 三次握手:生成tcp套接字—— SYN(80端口)报文段——IP数据报(加IP)——网关路由器——域间域内转发(RIP、OSPF、BGP)——到达服务器
  2. 抽取TCP报文段、生成链接套接字、产生TCP SYNACK报文段——封装成帧——转发——到达客户机
  3. ——分解到相应套接字——HTTP GET报文——封装:TCP报文段、数据报、链路帧——转发——到达服务器

(3)访问数据

  1. 服务器将访问的Web页面内容放入HTTP响应报文中——封装:TCP报文段、数据报、链路帧——转发——到达客户机
  2. 客户机解析出HTPP响应报文——经过浏览器渲染——呈现页面

** 简单说下多线程(常用函数和锁说下

线程是程序调度的基本单位,线程共享进程资源,如代码段、数据段、文件描述符表、当前工作目录、用户ID和组ID等。也拥有自己的一部分数据,如寄存器信息、自己的堆栈、私有数据、线程ID(TID)、上下文信息、、errno变量、信号屏蔽字、调度优先级等等。

有很多优点:

  1. 响应性高。阻塞和冗长操作是,可以继续执行其他任务,更高的响应。
  2. 资源共享。共享代码段和数据段。
  3. 经济。创建/切换一个线程的需要操作系统做的工作远比创建/切换一个新进程的要小得多。
  4. 可伸缩性。充分使用多个处理核,而单线程进程不能。

缺点:

  1. 数据共享会导致数据缺乏保护性
  2. 编写和调试更困难。

** 定义一个数据结构保证多个线程读写的线程安全。

利用单例模式懒汉式,设计一个多线程安全的机制。

// singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H

#include <iostream>
#include <mutex>
using namespace std;

// 单例 - 懒汉式/饿汉式公用
class Singleton
{
public:
    static Singleton* GetInstance();

private:
    Singleton() {}  // 构造函数(被保护)

private:
    static Singleton *m_pSingleton;  // 指向单例对象的指针
    static mutex m_mutex;  // 锁
};

#endif // SINGLETON_H
// singleton.cpp
#include "singleton.h"

// 单例 - 懒汉式(双检锁 DCL 机制)
Singleton *Singleton::m_pSingleton = NULL;
mutex Singleton::m_mutex;

Singleton *Singleton::GetInstance()
{
    if (m_pSingleton == NULL) {
        std::lock_guard<std::mutex> lock(m_mutex);  // 自解锁
        if (m_pSingleton == NULL) {
            m_pSingleton = new Singleton();
        }
    }
    return m_pSingleton;
}

 

** 冒泡算法的优化

  • 优化一:设置每轮冒泡是否进行了交换的标识,如果某轮没有交换,表明全局有序,直接跳出大循环。
  • 优化二:在每轮冒泡中设置一个标志,记录最后一次交换的位置,这么位置表示从这个位置以后,都是有序的,下一轮的冒泡就不用再比较标志后面的元素。

** 大量数据读写,数据的修改尽量不影响读和查询

其他的方法暂时不知道,目前知道的有两个:

  • 修改前,创建一个副本,修改的时候修改副本,修改完后再回写。
  • 设置分库和主从,主库修改,从库读。

** 内存泄漏是怎么引起的?怎么检查内存泄漏?

(1)什么是内存泄漏?

由于疏忽或错误,未能释放掉不再使用的内存。内存泄漏不是真正物理上消逝,而是分配某段空间后,失去对该段的控制。

(2)C++主要两种内存泄漏:

  • 堆内存泄漏。使用new/malloc申请的空间,没有显示用delete/free掉,以后这块内存不再时候,将导致内存泄漏。
  • 系统资源泄漏。程序使用系统分配的资源,比如 Bitmap、handle 、socket等,却没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少

(3)怎么检查内存泄漏?

  • VC自带的CRT:_CrtCheckMemory调试器和CRT调试堆函数,放在main函数的最后。原理:CRT会在程序结束前做清理工作,这时若是有内存没释放,就能定位出来文件名和位置。
  • 还有一个函数放在最前面,可使程序暂停在泄漏的内存第一次申请的地方。

(4)怎么减少内存泄漏?

  • 良好的编程习惯。使用了new/malloc申请了内存,及时用delete/free释放掉。
  • 将分配的内存的指针以链表的形式自行管理,使用完毕之后从链表中删除,程序结束时可检查改链表。
  • 智能指针

** 内存溢出

程序在申请内存时,没有足够的内存空间供其使用,如:

  • 申请一块比系统允许的更大的空间
  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
  • 数组或指针越界
  • 栈溢出。递归太多层。
  • 内存泄漏最终导致内存溢出。

** 野指针

指向被释放的或者访问受限内存的指针。造成原因

  • 未初始化的指针
  • 被free或者delete,但是未至为NULL的指针
  • 指针操作超越了变量的作用范围,比如返回指向栈内存的指针就是野指针。

** 宏定义max(a,b)

#define max(a,b)  (((a)>=(b))?(a):(b))

** MySQL的引擎有哪些?

 

** SQL查询语句,不用肉眼观察,怎么知道用了什么索引?

 

 

** C++11标准有什么改进,std::Move是什么?

 

 

** 54张牌,一半黑一半白,拿出红的再拿出黑的的概率

(2)待学习和改进的地方

 

百度测试岗位

(1)面试题

 

开放性问题,百度框测试

(2)待改进的地方

看一些软件工程的书,知道软件开发的流程。

项目要更深入,想到优化点。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值