为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
while(1)
sleep(1);
return 0;
}
该程序可以通过 Ctrl+\终止, 因为
组合键 Ctrl+\能够产生 SIGQUIT 信号,而该信号的捕捉函数尚未在程序中注册。
3、sigaction 信号处理机制
在 signal 处理机制下, 还有许多特殊情况需要考虑:
1、注册一个信号处理函数,并且处理完毕一个信号之后,是否需要重新注册,才能够捕捉下一个
信号;(不需要)
2、如果信号处理函数正在处理信号, 并且还没有处理完毕时,又发生了一个同类型的信号,这时
该怎么处理;(挨着执行),后续相同信号忽略(会多执行一次)。
3、如果信号处理函数正在处理信号,并且还没有处理完毕时,又发生了一个不同类型的信号,这
时该怎么处理;(跳转去执行另一个信号,之后再执行剩下的没有处理完的信号)
4、如果程序阻塞在一个系统调用(如 read(…))时,发生了一个信号,这时是让系统调用返回错误再
接着进入信号处理函数,还是先跳转到信号处理函数,等信号处理完毕后,系统调用再返回。—> 由下面具体说明:
**总结:**信号都是平等的无优先级。但是对于singal接口来说最多执行2次、打断。默认不能打断当前相同信号,可以被其他信号打断。另外一个信号会立即唤醒正在睡眠的进程。
eg:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
int g_iSeq = 0;
void SignHandler(int iSignNo)
{
int iSeq = g_iSeq++;
printf(“%d Enter SignHandler,signo:%d\n”,iSeq,iSignNo);
sleep(3);
printf(“%d Leave SignHandler,signo:%d\n”,iSeq,iSignNo);
}
int main()
{
char szBuf[8];
int iRet;
//不同的信号调用同一个处理函数
signal(SIGINT,SignHandler);
signal(SIGQUIT,SignHandler);
do{
iRet = read(STDIN_FILENO,szBuf,sizeof(szBuf)-1);
if(iRet < 0){
perror(“read fail.”);
break;
}
s
zBuf[iRet] = 0;
printf(“Get: %s”,szBuf);
}while(strcmp(szBuf,“quit\n”) != 0);
return 0;
}
程序运行时,针对于如下几种输入情况,看输出结果:
1、 [CTRL+c] [CTRL+c] (一个一个挨着执行)
2、 [CTRL+c] [CTRL+] (先执行 c 的进入, 被\打断, 转而执行\,
最后执行c的退出)
3、 hello [CTRL+] [Enter] (先执行中断, 没有任何输出)
4、 [CTRL+] hello [Enter] (先执行中断, 输出内容)
5、 hel [CTRL+] lo[Enter] (先执行中断, 只输出 lo)
4、sigaction 信号处理注册
函数原型:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- sigaction 也用于注册一个信号处理函数
- 参数 signum 为需要捕捉的信号
- 参数 act 是一个结构体, 里面包含信号处理函数地址、 处理方式等信息
- 参数 oldact 是一个传出参数, sigaction 函数调用成功后, oldact 里面包含以前对 signum 的处理方式的信息,通常为 NULL,如果函数调用成功,将返回 0,否则返回-1
**1、**结构体 struct sigaction的原型为:
struct sigaction {
void (*sa_handler)(int); //老类型的信号处理函数指针
void (*sa_sigaction)(int, siginfo_t *,void *);//新类型的信号处理函数指针
sigset_t sa_mask; //将要被阻塞的信号集合
int sa_flags;
//信号处理方式掩码(SA_SIGINFO)
void(*sa_restorer)(void);
//保留, 不要使
};
1、字段sa_handler是一个函数指针,用于指向原型为void handler(int)的信号处理函数地址,
即老类型 的信号处理函数(如果用这个再将 sa_flags = 0,就等同于 signal()函数)
2、字段 sa_sigaction 也是一个函数指针,用于指向原型为:
void handler(int iSignNum, siginfo_t *pSignInfo, void *pReserved);
的信号处理函数,即新类型的信号处理函数
- iSignNum: 传入的信号
- pSignInfo: 与该信号相关的一些信息,它是个结构体
- pReserved: 保留,现没用,通常为NULL
3、字段sa_handler和sa_sigaction只应该有一个生效,如果想采用老的信号处理机制,就应该让
sa_handler指向正确的信号处理函数,并且让字段sa_flags为0;否则应该让sa_sigaction指向正确
的信号处理函数,并且让字段sa_flags包含SA_SIGINFO选项。
4、字段sa_mask是一个包含信号集合的结构体,该结构体内的信号表示在进行信号处理时,将要
被阻塞的信号。
- 针对sigset_t 结构体,有一组专门的函数对它进行处理,它们是:#include <signal.h>
-
- int sigemptyset(sigset_t *set); //清空信号集合 set
- int sigfillset(sigset_t *set); //将所有信号填充进set中
- int sigaddset(sigset_t *set, int signum); //往set中添加信号signum
- int sigdelset(sigset_t *set, int signum); //从 set 中移除信号 signum
- int sigismember(const sigset_t *set, int signum); //判断signum是否包含在set中(是:返回1,否:0)
- int sigpending(sigset_t *set); //将被阻塞的信号集合由参数set指针返回(挂起信号)
- int sigemptyset(sigset_t *set); //清空信号集合 set
- 其中,对于函数sigismember而言,如果signum在set集中,则返回 1;不在,则返回0;出错时返回-1.其他的函数都是成功返回0,失败返回-1。
eg: 如果打算在处理信号SIGINT时,只阻塞对SIGQUIT信号的处理,可以用如下方法:
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = newHandler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGQUIT);
sigaction(SIGINT,&act,NULL);
5、字段 sa_flags是一组掩码的合成值,指示信号处理时所应该采取的一些行为,各掩码的含义为:
eg:用sigaction 实现和signal(只能传递一个参数)一样的功能。
#include<signal.h>
#include<stdio.h>
void handle(int signo)
{
printf(“signo: %d\n”,signo);
}
m
ain()
{
struct sigaction st;
st.sa_handler = handle;
st.sa_flags = 0;
sigaction(SIGINT,&st,NULL);
while(1)
{
sleep(1);
}
}
2、用sigaction 实现调用新的信号处理函数
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
int g_iSeq = 0;
void SignHandlerNew(int iSignNo,siginfo_t *pInfo,void *pReserved)
{
int iSeq = g_iSeq++;
printf("%d Enter
SignHandlerNew,signo:%d\n",iSeq,iSignNo);
sleep(3);
printf(“%d Leave SignHandlerNew,signo:%d\n”,iSeq,iSignNo);
}
in
t main()
{
struct sigaction act;
act.sa_sigaction = SignHandlerNew;
act.sa_flags = SA_SIGINFO;
sigaction(SIGINT,&act,NULL);
sigaction(SIGQUIT,&act,NULL);
while(1)
{
sleep(1);
}
r
eturn 0;
}
5、sigprocmask 信号阻塞
函数sigaction中设置的被阻塞信号集合只是针对于要处理的信号,例如
struct sigaction act;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGQUIT);
sigaction(SIGINT,&act,NULL);
表示只有在处理信号SIGINT时,才阻塞信号 SIGQUIT;(重点区分)
函数sigprocmask 是全程阻塞,在 sigprocmask 中设置了阻塞集合后, 被阻塞的信号将不能再被信号
处理函数捕捉,直到重新设置阻塞信号集合。
原型为:
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数 how 的值为如下3者之一:
a: SIG_BLOCK ,将参数 2 的信号集合添加到进程原有的阻塞信号集合中
b: SIG_UNBLOCK ,从进程原有的阻塞信号集合移除参数2中包含的信号
c: SIG_SETMASK, 重新设置进程的阻塞信号集为参数 2 的信号集
参数 set 为阻塞信号集
参数 oldset 是传出参数, 存放进程原有的信号集, 通常为 NULL
**eg:**添加全程阻塞
//屏蔽掉 SIGQUIT 信号
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet,SIGQUIT);
sigprocmask(SIG_BLOCK,&sigSet,NULL);
struct sigaction act;
act.sa_sigaction=SignHandlerNew;
act.sa_flags=SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaction(SIGINT,&act,NULL);
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ldset 是传出参数, 存放进程原有的信号集, 通常为 NULL
**eg:**添加全程阻塞
//屏蔽掉 SIGQUIT 信号
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet,SIGQUIT);
sigprocmask(SIG_BLOCK,&sigSet,NULL);
struct sigaction act;
act.sa_sigaction=SignHandlerNew;
act.sa_flags=SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaction(SIGINT,&act,NULL);
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!