差不多可以结束秋招了(C++/存储岗位)
目前手里有蚂蚁金服的offer和网易面试通过的短信,分享一下面经吧,感谢牛客网上前辈的面经。
自己面了阿里(3面技术+1轮HR),百度(3轮技术),网易(2轮技术+1轮HR)。
百度的面试感觉重视写代码与实习,我后来问了内推我的人,二面写代码慢了,给了个pending状态,不过代码题其实都是剑指offer上的
百度一二面
单链表反转,复杂链表复制,time_wait状态。Syn_flood攻击,time_wait状态会带来什么问题。
Explict关键字的作用,
为啥虚函数要定义成virtual的
三次握手过程,为啥要三次握手
大文件中找重复记录次数最多的记录
链表的回文判断(链表每个节点存一个字符,判断该链表所有结点组成的字符串是不是回文字符串)
C++智能指针循环引用
线程池的原理
阿里一、二面,问的问题忘记了,但是记得一个手写代码题,让实现一个Rational类,用C++写一个有理数类,class Rational,实现基本的加减乘除和输入输出操作。贴下自己的代码(可能实现的不够完全):
#include<iostream> template<typename T> class Rational { public: Rational(); Rational(T x); Rational(T x, T y); bool operator== (const Rational<T>& r1) const; Rational<T> & operator +=(const Rational<T> &r1); Rational<T> & operator -=(const Rational<T> &r1); Rational<T> & operator *=(const Rational<T> &r1); Rational<T> & operator /=(const Rational<T> &r1); template<typename T1> friend std::ostream& operator<< (std::ostream& os, const Rational<T1>& r); template<typename T1> friend std::istream& operator>> (std::istream& is, Rational<T1>& r); friend const Rational<T> operator + (const Rational<T> &r1, const Rational<T> &r2) { Rational<T> r = r1; return __doAdd(&r, r2); } friend const Rational<T> operator - (const Rational<T> &r1, const Rational<T> &r2) { Rational<T> r = r1; return __doSub(&r, r2); } friend const Rational<T> operator * (const Rational<T> &r1, const Rational<T> &r2) { Rational<T> r = r1; return __doMult(&r, r2); } friend const Rational<T> operator / (const Rational<T> &r1, const Rational<T> &r2) { Rational<T> r = r1; return __doDiv(&r, r2); } private: static T gcd(T p, T q); T nume_; //numerator T der_; //der number template<typename T1> friend Rational<T1>& __doAdd(Rational<T1> *ths, const Rational<T1>& r); template<typename T1> friend Rational<T1> &__doSub(Rational<T1> *ths, const Rational<T1> &r); template<typename T1> friend Rational<T1> &__doMult(Rational<T1> *ths, const Rational<T1> &r); template<typename T1> friend Rational<T1> &__doDiv(Rational<T1> *ths, const Rational<T1> &r); }; template<typename T> Rational<T>& __doAdd(Rational<T> *ths, const Rational<T> &r) { if (ths->der_ == r.der_) { ths->nume_ += r.nume_; return *ths; } ths->nume_ = ths->nume_*r.der_ + r.nume_*ths->der_; ths->der_ = ths->der_* r.der_; T gcd_res = Rational<T>::gcd(ths->nume_, ths->der_); ths->nume_ /= gcd_res; ths->der_ /= gcd_res; return *ths; } template<typename T> Rational<T>& Rational<T>::operator+= (const Rational<T> &r1) { return __doAdd(this, r1); } template<typename T> Rational<T> &__doSub(Rational<T> *ths, const Rational<T> &r) { Rational<T> rr(r); rr.nume_ = -rr.nume_; return __doAdd(ths, rr); } template<typename T> Rational<T>& Rational<T>::operator-=(const Rational<T> &r1) { return __doSub(this, r1); } template<typename T> Rational<T> &__doMult(Rational<T> *ths, const Rational<T> &r) { ths->der_ *= r.der_; ths->nume_ *= r.nume_; T gcd_res = Rational<T>::gcd(ths->nume_, ths->der_); ths->nume_ /= gcd_res; ths->der_ /= gcd_res; return *ths; } template<typename T> Rational<T>& Rational<T>::operator*=(const Rational<T> &r1) { return __doMult(this, r1); } template<typename T> Rational<T> &__doDiv(Rational<T> *ths, const Rational<T> &r) { if (r == 0) { std::cerr << "divisor can't be zero." << std::endl; return *ths; } Rational<T> rr; rr.nume_ = r.der_; rr.der_ = r.nume_; return __doMult(ths, rr); } template<typename T> Rational<T>& Rational<T>::operator/=(const Rational<T> &r1) { return __doDiv(this, r1); } template<typename T> std::istream & operator>>(std::istream& is, Rational<T>& r1) { char c; T nume, der=1; is >> nume; c=getchar(); if (c == '\n') { r1.nume_ = nume; r1.der_ = 1; return is; } is >> der; Rational<T> r(nume,der); if (is) { r1 = r; } else { //may be output other error information std::cerr <<"input error" << std::endl; r1 = Rational<T>(); } return is; } template<typename T> std::ostream& operator<<(std::ostream& os, const Rational<T>& r1) { if (r1.nume_ == 0) { return os << 0; } else if (r1.nume_ == r1.der_) { return os << 1; } else if (r1.der_ == 1) { return os << r1.nume_; } return os << r1.nume_ << "/" << r1.der_; } template<typename T> Rational<T>::Rational() :nume_(0), der_(1) {} template<typename T> Rational<T>::Rational(T a) : nume_(a), der_(1) {} template<typename T> Rational<T>::Rational(T a, T b) : nume_(a), der_(b) { if (der_ == 0) { std::cerr << "denominator can't be zero." << std::endl; der_ = 1; return; } else if (der_ < 0) { //let nume < 0 nume_ = -nume_; der_ = -der_; } } template<typename T> bool Rational<T>::operator==(const Rational<T> & r1) const { if (r1.nume_ == nume_ && r1.der_ == der_) { return true; } return false; } template<typename T> T Rational<T>::gcd(T a, T b) { while (b != 0) { T r = b; b = a % b; a = r; } return a; } template<typename T> const Rational<T> operator + (const Rational<T> &r1, const T& a) { Rational<T> r = r1; return __doAdd(&r, Rational<T>(a)); } int main(int argc, char* argv[]) { Rational<int> a(1, 3); Rational<int> b = 3; Rational<int> c(a + b + Rational<int>(1, 3)); std::cout << "a=" << a << std::endl; std::cout << "b=" << b << std::endl; std::cout << "c=" << c << std::endl; Rational<int> e(1, 3); std::cout << "1/3*1/3= " << a*e << std::endl; std::cout << "1/3-1/3= " << a - e << std::endl; std::cout << "1/3 / 1/3= " << a / e << std::endl; a += b; std::cout << "a+=b: " << a << std::endl; a -= b; std::cout << "a-=b: " << a << std::endl; a *= b; std::cout << "a*=b: " << a << std::endl; a /= b; std::cout << "a/=b: " << a << std::endl; std::cout << "Please input a Rational number ( a or a/b are both OK)" << std::endl; Rational<int> d; std::cin >> d; std::cout << "value d+1=" << d + Rational<int>(1) << std::endl; std::cout << "value d-1=" << d - 1 << std::endl; std::cout << "value d*2=" << d * 2 << std::endl; std::cout << "value d/2=" << d / 2 << std::endl; return 0; }
阿里三面
除项目外问的问题
1. Concurrent Memtable HashTable
2. Shard_ptr与unique_ptr实现机制,怎么说清楚它们的用法 (C++11 delete)
网易1面
全程聊了30分钟项目,然后就是C++基础题,牛客网的面经上都有
网易2面
仍然聊项目,但是还聊了分布式协议Raft,以及Raft协议的问题,这块不是很懂,因为没有看过实现。