差不多可以结束秋招了(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协议的问题,这块不是很懂,因为没有看过实现。


