面试经验4-19
-
如何实现memcpy?
如果从头实现memcpy,那么遇见src<dst的时候,并且有重叠的时候就嘎了。
#include <bits/stdc++.h> using namespace std; using LL = long long; const int N = 1e5 + 5; const int INF = 2147483647; int a[N]; int n; void my_memcpy(void* dst, const void* src, size_t size){ if(dst==nullptr||src==nullptr)return; if(src+size>dst){ char* lst_dst=(char *)dst+size-1; const char * lst_src=(char*)src+size-1; while(size--){ *lst_dst--=*lst_src--; } }else{ char* lst_dst=(char *)dst; const char * lst_src=(char*)src; while(size--){ *lst_dst++=*lst_src++; } } } int main(){ cin >> n; for(int i=0;i<n;++i){ cin >> a[i]; } my_memcpy(a+4, a, 5*sizeof(int)); for(int i=0;i<n;++i){ cout<<a[i]<<endl; } return 0; }
-
c++ forward的作用。
首先介绍一下什么是左值引用和什么是右值引用。左值引用就是一个持久性变量的引用(可以取地址)。右值引用是一个常量(临时值)的引用。左值引用只能绑定左值。右值引用只能绑定右值。右值引用不能绑定右值引用变量。因为变量是左值。
再介绍一下完美转发:在函数模版中,将参数原封不动的转发给其他函数。包括参数的类型,值。
比如下面的例子:
#include <iostream> #include <utility> void func(int& x){ std::cout<<"lvale: "<< x <<std::endl; } void func(int&& x){ std::cout<<"rvale: "<< x <<std::endl; } template <typename T> void wrapper(T&& arg){ func(std::forward<T>(arg)); } int main(){ int i=4; wrapper(i); wrapper(5); return 0; }
使用了std::forward函数进行了完美转发。T&&表示可以接受某一类型的左值和右值。
-
介绍一下move函数:
std::move是一个用于将左值强制转为右值引用的函数。转换了对象的类型,而没有改变对象的内容。节省了程序的时间和空间开销。参数是右值的时候,不需要复制。简而言之,move就是用来改变对象的状态或者所有权的。
#include <iostream> #include <string> #include <vector> using namespace std; int main() { string str = "hello"; cout << "before str: " << str << endl; vector<string> vstr; vstr.emplace_back(std::move(str)); cout << "after str: " << str << endl; return 0; } //result //before str: hello //after str:
-
c++中智能指针是一种管理动态内存的工具。进行自动的内存管理,避免手动分配和释放内存带来的错误。
unique_ptr是资源管理的唯一对象。可以转移给其他unique_ptr,但是有所有权的unique_ptr析构的时候,被管理的对象将会被释放。
shared_ptr允许多个shared_ptr共享同一个对象。在最后一个share_ptr离开他的作用域的时候,他便自动释放其管理的对象。shared_ptr用计数的方式追踪有多少个share_ptr对象指向同一个对象。创建一个share_ptr引用就加1,销毁就减1,引用计数为0的时候,shared_ptr就会删除管理的对象。这个计数器的实现原理是,每个share_ptr都会有一个指向counter的指针。
weak_ptr用于于shared_ptr共享一个对象。不会增加引用计数,它不会阻止管理对象被删除。用lock成员函数从weak_ptr创建一个shared_ptr对象。这就可以访问被管理的对象,这样可以减少shared_ptr之间循环引用的问题。
#include <iostream> #include <string> #include <vector> #include <memory> int main(){ std::shared_ptr<int> p1=std::make_shared<int>(10); std::cout<<p1.use_count()<<std::endl; std::shared_ptr<int> p2=p1; std::cout<<p2.use_count()<<std::endl; std::weak_ptr<int> p3=p1; std::cout<<p3.use_count()<<std::endl; p1=nullptr; std::cout<<p1.use_count()<<std::endl; //p2.reset(); std::cout<<p2.use_count()<<std::endl; return 0; }
-
主流电商用的多线程还是多进程
多线程。多线程的优势是:
a. 资源共享:共享内存空间,数据和变量。
b. 上下文切换快速。线程切换代价更低,共享同一进程的地址空间和资源。
c. 适合现代多核处理器。
-
HTTP的头部里有什么内容:
Host,被请求资源的主机名以及端口号。User-agent:制定客户端类型以及版本号。Referer:指定的源URL。Accept-language,接受的语言类型以及优先级。Cookie用来识别客户端身份。
-
c++中管理内存的方式。
手动管理,new和delete。智能指针:三种智能指针。RAII,资源获取即初始化。模版库。
-
unique_ptr怎么赋值给另一个unique_ptr。
用std::move;
-
多线程开发的问题:如何实现互斥和同步。c++11开始,支持语言级别的多线程。与平台无关。
保护共享数据的问题:互斥量。
-