为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
private:
std::ostream & m_os;
};
// progress_display --------------------------------------------------------//
// progress_display displays an appropriate indication of
// progress at an appropriate place in an appropriate form.
// NOTE: (Jan 12, 2001) Tried to change unsigned long to boost::uintmax_t, but
// found some compilers couldn’t handle the required conversion to double.
// Reverted to unsigned long until the compilers catch up.
class progress_display : private noncopyable
{
public:
explicit progress_display( unsigned long expected_count_,
std::ostream & os = std::cout,
const std::string & s1 = “\n”, //leading strings
const std::string & s2 = “”,
const std::string & s3 = “” )
// os is hint; implementation may ignore, particularly in embedded systems
: noncopyable(), m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count_); }
void restart( unsigned long expected_count_ )
// Effects: display appropriate scale
// Postconditions: count()==0, expected_count()==expected_count_
{
_count = _next_tic_count = _tic = 0;
expected_count = expected_count;
m_os << m_s1 << "0% 10 20 30 40 50 60 70 80 90 100%\n"
<< m_s2 << "|----|----|----|----|----|----|----|----|----|----|"
<< std::endl // endl implies flush, which ensures display
<< m_s3;
if ( !_expected_count ) _expected_count = 1; // prevent divide by zero
} // restart
unsigned long operator+=( unsigned long increment )
// Effects: Display appropriate progress tic if needed.
// Postconditions: count()== original count() + increment
// Returns: count().
{
if ( (_count += increment) >= _next_tic_count ) { display_tic(); }
return _count;
}
unsigned long operator++() { return operator+=( 1 ); }
unsigned long count() const { return _count; }
unsigned long expected_count() const { return _expected_count; }
private:
std::ostream & m_os; // may not be present in all imps
const std::string m_s1; // string is more general, safer than
const std::string m_s2; // const char *, and efficiency or size are
const std::string m_s3; // not issues
unsigned long _count, _expected_count, _next_tic_count;
unsigned int _tic;
void display_tic()
{
// use of floating point ensures that both large and small counts
// work correctly. static_cast<>() is also used several places
// to suppress spurious compiler warnings.
unsigned int tics_needed = static_cast((static_cast(_count)
/ static_cast(_expected_count)) * 50.0);
do { m_os << ‘*’ << std::flush; } while ( ++_tic < tics_needed );
_next_tic_count =
static_cast((_tic/50.0) * static_cast(_expected_count));
if ( _count == _expected_count ) {
if ( _tic < 51 ) m_os << ‘*’;
m_os << std::endl;
}
} // display_tic
};
} // namespace boost
#endif // BOOST_PROGRESS_HPP
#### 3.data\_time库
data\_time库需要编译才能使用,data\_time库包括两个部分,处理日期的gregorian,处理时间的posix\_time,它们各自需要包含的头文件如下:
//处理日期的组件
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian
//处理时间的组件
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time
##### 3.1gregorian
用下面一段代码来测试一下这个模块
#include
using namespace std;
//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
//
void case1()
{
date d1;
date d2(2010,1,1);
date d3(2000, Jan , 1);
date d4(d2);
assert(d1 == date(not_a_date_time));
assert(d2 == d4);
assert(d3 < d4);
}
//
void case2()
{
date d1 = from_string(“1999-12-31”);
date d2 ( from_string(“2015/1/1”) );
date d3 = from_undelimited_string(“20011118”) ;
cout << d1 << d2 << d3 << endl;
cout << day_clock::local\_day() << endl;
cout << day_clock::universal\_day() << endl;
}
//
void case3()
{
date d1(neg_infin);
date d2(pos_infin);
date d3(not_a_date_time);
date d4(max_date_time);
date d5(min_date_time);
cout << d1 << d2 << d3 << d4 << d5 << endl;
try
{
//date d1(1399,12,1);
//date d2(10000,1,1);
date d3(2017,2,29);
}
catch(std::exception& e)
{
cout << e.what() << endl;
}
}
//
void case4()
{
date d(2017,6,1);
assert(d.year() == 2017);
assert(d.month() == 6);
assert(d.day() == 1);
date::ymd_type ymd = d.year\_month\_day();
assert(ymd.year == 2017);
assert(ymd.month == 6);
assert(ymd.day == 1);
cout << d.day\_of\_week() << endl;
cout << d.day\_of\_year() << endl;
assert(d.end\_of\_month() == date(2017,6,30));
cout << date(2015,1,10).week\_number() << endl;
cout << date(2016,1,10).week\_number() << endl;
cout << date(2017,1,10).week\_number() << endl;
assert(date(pos_infin).is\_infinity() );
assert(date(pos_infin).is\_pos\_infinity() );
assert(date(neg_infin).is\_neg\_infinity() );
assert(date(not_a_date_time).is\_not\_a\_date() );
assert(date(not_a_date_time).is\_special() );
assert(!date(2017,5,31).is\_special() );
}
//
void case5()
{
date d(2017,1,23);
cout << to\_simple\_string(d) << endl;
cout << to\_iso\_string(d) << endl;
cout << to\_iso\_extended\_string(d) << endl;
cout << d << endl;
//cout << "input date:";
//cin >>d;
//cout << d;
}
//
void case6()
{
date d(2017,5,20);
tm t = to_tm(d);
assert(t.tm_hour == 0 && t.tm_min == 0);
assert(t.tm_year == 117 && t.tm_mday == 20);
date d2 = date\_from\_tm(t);
assert(d == d2);
}
//
void case7()
{
days dd1(10), dd2(-100), dd3(255);
assert( dd1 > dd2 && dd1 < dd3);
assert( dd1 + dd2 == days(-90));
assert((dd1 + dd3).days() == 265);
assert( dd3 / 5 == days(51));
weeks w(3);
assert(w.days() == 21);
months m(5);
years y(2);
months m2 = y + m;
assert(m2.number\_of\_months() == 29);
assert((y \* 2).number\_of\_years() == 4);
}
//
void case8()
{
date d1(2000,1,1),d2(2017,11,18);
cout << d2 - d1 << endl;
assert(d1 + (d2 - d1) == d2);
d1 += days(10);
assert(d1.day() == 11);
d1 += months(2);
assert(d1.month() == 3 && d1.day() == 11);
d1 -= weeks(1);
assert(d1.day() == 4);
d2 -= years(10);
assert(d2.year() == d1.year() + 7);
{
date d1(2017,1,1);
date d2 = d1 + days(pos_infin);
assert(d2.is\_pos\_infinity());
d2 = d1 + days(not_a_date_time);
assert(d2.is\_not\_a\_date());
d2 = date(neg_infin);
days dd = d1 - d2;
assert(dd.is\_special() && !dd.is\_negative());
}
{
date d(2017,3,30);
d -= months(1);
d -= months(1);
d += months(2);
assert(d.day() == 31);
}
}
//
void case9()
{
date_period dp1(date(2017,1,1), days(20));
date_period dp2(date(2017,1,1), date(2016,1,1));
date_period dp3(date(2017,3,1), days(-20));
date_period dp(date(2017,1,1), days(20));
assert(!dp.is\_null());
assert(dp.begin().day() == 1);
assert(dp.last().day() == 20);
assert(dp.end().day() == 21);
assert(dp.length().days() == 20);
{
date_period dp1(date(2017,1,1), days(20));
date_period dp2(date(2017,2,19), days(10));
cout << dp1; //[2010-Jan-01/2010-Jan-20]
assert(dp1 < dp2);
}
}
//
int main()
{
case1();
case2();
case3();
case4();
case5();
case6();
case7();
case8();
case9();
}
##### 3.2date\_period
data\_time库使用date\_period来表示日期区间的概念,它是时间轴上的一个左闭右开的区间,其端点是两个date对象。日期区间的左边界必须小于右边界,否则date\_period将表示一个无效的日期区间。
date\_period的类摘要如下:
class date_period
{
public:
period(date, date);
period(date, days);
date begin() const;
date end() const;
date last() const;
days length() const;
bool is\_null() const;
bool operator==(const period &) const;
bool operator<(const period &) const;
void shift(const days &);
void expand(const days &);
bool contains(const date &) const;
bool contains(const period &) const;
bool intersects(const period &) const;
bool is\_adjacent(const period &) const;
bool is\_before(const date &) const;
bool is\_after(const date &) const;
period intersection(const date &) const;
period merge(const period &) const;
period span(const period &) const;
};
用一段代码来测试一下
#include
using namespace std;
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
//
void case1()
{
date_period dp(date(2017,1,1), days(20));
dp.shift(days(3));
assert(dp.begin().day() == 4);
assert(dp.length().days() == 20);
dp.expand(days(3));
assert(dp.begin().day() == 1);
assert(dp.length().days() == 26);
}
//
void case2()
{
date_period dp(date(2010,1,1), days(20));
assert(dp.is\_after(date(2009,12,1)));
assert(dp.is\_before(date(2010,2,1)));
assert(dp.contains(date(2010,1,10)));
date_period dp2(date(2010,1,5), days(10));
assert(dp.contains(dp2));
assert(dp.intersects(dp2));
assert(dp.intersection(dp2) == dp2);
date_period dp3(date(2010,1,21), days(5));
assert(!dp3.intersects(dp2));
assert(dp3.intersection(dp2).is\_null());
assert(dp.is\_adjacent(dp3));
assert(!dp.intersects(dp3));
}
//
void case3()
{
date_period dp1(date(2010,1,1), days(20));
date_period dp2(date(2010,1,5), days(10));
date_period dp3(date(2010,2,1), days(5));
date_period dp4(date(2010,1,15), days(10));
assert( dp1.contains(dp2) && dp1.merge(dp2) == dp1);
assert(!dp1.intersects(dp3) && dp1.merge(dp3).is\_null());
assert( dp1.intersects(dp2) && dp1.merge(dp4).end() == dp4.end());
assert( dp1.span(dp3).end() == dp3.end());
}
//
void case4()
{
date d(2007,9,28);
day_iterator d_iter(d);
assert(d_iter == d);
++d_iter;
assert(d_iter == date(2007,9,29));
year_iterator y\_iter(\*d_iter, 10);
assert(y_iter == d + days(1));
++y_iter;
assert(y_iter->year() == 2017);
day_iterator iter(day_clock::local\_day());
++iter;
//iter += 5;
//std::advance(iter, 5);
}
//
void case5()
{
typedef gregorian_calendar gre_cal;
cout << “Y2017 is "
<< (gre_cal::is_leap_year(2017)?”“:“not”)
<< " a leap year.” << endl;
assert(gre_cal::end_of_month_day(2017, 2) == 28);
}
//
void case6()
{
date d(2017,1,23);
date d\_start(d.year(), d.month(), 1);
date d_end = d.end\_of\_month();
for(day_iterator d\_iter(d_start);
d_iter <= d_end; ++d_iter)
{
cout << \*d_iter << " " <<
d_iter->day\_of\_week()<< endl;
}
}
//
void case7()
{
date d(2017,1,23);
date d18years = d + years(18);
cout << d18years << " is "
<< d18years.day\_of\_week()<< endl;
int count = 0;
for (day_iterator d\_iter(date(d18years.year(),1,1));
d_iter <= d18years.end\_of\_month(); ++d_iter)
{
if (d_iter->day\_of\_week() == Sunday)
{
++count;
}
}
cout << "total " << count << " Sundays." << endl;
count = 0;
for (month_iterator m\_iter(date(d18years.year(),1,1));
m_iter < date(d18years.year() + 1 ,1, 1); ++m_iter)
{
count += m_iter->end\_of\_month().day();
}
cout << "total " << count << " days of year." << endl;
}
//
class credit_card
{
public:
string bank_name;
int bill_day_no;
credit\_card(const char\* bname, int no):
bank\_name(bname), bill\_day\_no(no){}
int calc\_free\_days(date consume_day = day_clock::local\_day()) const
{
date bill\_day(consume_day.year(), consume_day.month(), bill_day_no);
if (consume_day > bill_day)
{
bill_day += months(1);
}
return (bill_day - consume_day).days() + 20;
}
friend bool operator<(const credit_card& l, const credit_card& r)
{
return l.calc\_free\_days() < r.calc\_free\_days();
}
};
void case8()
{
credit_card a(“A bank”, 25);
credit_card b(“B bank”, 12);
credit_card tmp = std::max(a, b);
cout << "You should use " << tmp.bank_name
<< ", free days = " << tmp.calc\_free\_days() << endl;
}
int main()
{
case1();
case2();
case3();
case4();
case5();
case6();
case7();
case8();
}
#### 4.posix\_time
date\_time库的时间功能位于命名空间boost::posix\_time,需要包含的头文件如下
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
从概念上来说,时间是日期的进一步细化,相当于在日期”天“的量级之下增加了”时分秒“的概念
直接上测试代码
#include
using namespace std;
//#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
#include <boost/date_time/gregorian/gregorian.hpp>
using namespace boost::gregorian;
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
//
void case1()
{
{
time_duration td = duration_from_string(“1:10:30:001”);
cout << td << endl;
time_duration td1(1,10,30,1000);
time_duration td2(1,60,60,1000\*1000\* 6 + 1000);
}
hours h(1);
minutes m(10);
seconds s(30);
millisec ms(1);
time_duration td = h + m + s + ms;
time_duration td2 = hours(2) + seconds(10);
cout << td << td2 << endl;
}
//
void case2()
{
time_duration td(1,10,30,1000);
assert(td.hours() == 1 && td.minutes() == 10 && td.seconds() == 30);
assert(td.total_seconds() == 1*3600+ 10*60 + 30);
#ifndef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
assert(td.total_milliseconds() == td.total_seconds()*1000 + 1);
assert(td.fractional_seconds() == 1000);
#endif
hours h(-10);
assert(h.is\_negative());
time_duration h2 = h.invert\_sign();
assert(!h2.is\_negative() && h2.hours() == 10);
time_duration td1(not_a_date_time);
assert(td1.is\_special() && td1.is\_not\_a\_date\_time());
time_duration td2(neg_infin);
assert(td2.is\_negative() && td2.is\_neg\_infinity());
}
//
void case3()
{
time_duration td1 = hours(1);
time_duration td2 = hours(2) + minutes(30);
assert(td1 < td2);
assert((td1+td2).hours() == 3);
assert((td1-td2).is_negative());
assert(td1 * 5 == td2 * 2);
assert((td1/2).minutes() == td2.minutes());
time_duration td(1,10,30,1000);
cout << to\_simple\_string(td) << endl;
cout << to\_iso\_string(td) << endl;
}
//
void case4()
{
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
time_duration td(1,10,30,1000);
cout << td;
assert(td.total_milliseconds() ==
td.total_seconds()*1000);
assert(td.fractional\_seconds() ==1000);
assert(time_duration::unit()\*1000\*1000\*1000 == seconds(1));
assert(td.resolution() == boost::date_time::nano);
assert(td.num\_fractional\_digits() == 9);
#endif
}
//
void case5()
{
ptime p(date(2017,7,7), hours(1));
ptime p1 = time_from_string(“2017-7-7 01:00:00”);
ptime p2 = from_iso_string(“20170707T010000”);
cout << p1 << endl << p2;
{
ptime p1 = second_clock::local\_time();
ptime p2 = microsec_clock::universal\_time();
cout << p1 << endl << p2;
}
}
//
void case6()
{
ptime p(date(2010,3,20), hours(12)+minutes(30));
date d = p.date();
time_duration td = p.time\_of\_day();
assert(d.month() == 3 && d.day() == 20);
assert(td.total\_seconds() == 12\*3600 + 30\*60);
ptime p1(date(2010,3,20), hours(12)+minutes(30));
ptime p2 = p1 + hours(3);
assert(p1 < p2);
assert(p2 - p1 == hours(3));
p2 += months(1);
assert(p2.date().month() == 4);
cout << endl;
{
ptime p(date(2017,2,14), hours(20));
cout << to\_simple\_string(p) << endl;
cout << to\_iso\_string(p) << endl;
cout << to\_iso\_extended\_string(p) << endl;
}
}
//
void case7()
{
ptime p(date(2017,5,20), hours(14));
tm t = to_tm§;
assert(t.tm_year == 117 && t.tm_hour == 14);
assert(ptime_from_tm(t) == p);
ptime p2 = from\_time\_t(std::time(0));
assert(p2.date() == day_clock::local\_day());
cout << to\_time\_t(p2) << endl;
}
//
void case8()
{
ptime p(date(2017,1,1),hours(12)) ;
time_period tp1(p, hours(8));
time_period tp2(p + hours(8), hours(1));
assert(tp1.end() == tp2.begin() && tp1.is_adjacent(tp2));
assert(!tp1.intersects(tp2));
tp1.shift(hours(1));
assert(tp1.is\_after(p));
assert(tp1.intersects(tp2));
tp2.expand(hours(10));
assert(tp2.contains(p) && tp2.contains(tp1));
}
//
void case9()
{
ptime p(date(2017,5,31),hours(10)) ;
for (time_iterator t_iter(p, minutes(10));
t_iter < p + hours(1); ++ t_iter)
{
cout << *t_iter << endl;
}
}
//
template
class basic_ptimer
{
public:
basic_ptimer()
{ restart();}
void restart()
{ _start_time = Clock::local_time(); }
void elapsed() const
{ cout << Clock::local_time() - _start_time; }
~basic_ptimer()
{ elapsed(); }
private:
ptime _start_time;
};
typedef basic_ptimer<microsec_clock> ptimer;
typedef basic_ptimer<second_clock> sptimer;
class work_time
{
public:
typedef map<time_period, string> map_t;
private:
map_t map_ts;
void init()
{
ptime p(day_clock::local_day());
map_ts[time\_period(p, hours(9))] = "It's too early, just relax.\n";
p += hours(9);
map_ts[time\_period(p, hours(3)+ minutes(30))] = "It's AM, please work hard.\n";
p += hours(3)+ minutes(30);
map_ts[time\_period(p, hours(1))] = "It's lunch time, are you hungry?\n";
p += hours(1);
map_ts[time\_period(p, hours(4)+minutes(30))] = "It's PM, ready to go home.\n";
p += hours(4)+ minutes(30);
map_ts[time\_period(p, hours(6))] = "Are you still working? you do need a rest.\n";
最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
资料预览
给大家整理的视频资料:
给大家整理的电子书资料:
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
30))] = “It’s AM, please work hard.\n”;
p += hours(3)+ minutes(30);
map_ts[time_period(p, hours(1))] = “It’s lunch time, are you hungry?\n”;
p += hours(1);
map_ts[time_period(p, hours(4)+minutes(30))] = “It’s PM, ready to go home.\n”;
p += hours(4)+ minutes(30);
map_ts[time_period(p, hours(6))] = “Are you still working? you do need a rest.\n”;
最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
资料预览
给大家整理的视频资料:
[外链图片转存中…(img-U81Er6bR-1715703422771)]
给大家整理的电子书资料:
[外链图片转存中…(img-NsuGnA9o-1715703422771)]
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!