栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux,数据库,C++常见面试题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux,数据库,C++常见面试题

linux开机的步骤
linux开机步骤

运维的一些小题目

在/tmp/目录下创建test.txt文件,内容为: Hello,World! ,用一个命令写出来: echo “Hello,World!”

/tmp/test.txt

用vi命令编辑test.txt,如何跳转到末行,首行,行首、行末,如何在光标行下一行插入,如何复制5行,删除10行,查找jingfeng的字符、把jingfeng替换为jfedu.net:
末行: G 首行: gg 行首: ^ 行末: $ 光标行下一行插入: o 复制5行:5yy 删除10行:10dd
替换::%s/jingfeng/jfedu.net/g

查找linux系统下以txt结尾,30天没有修改的文件大小大于20K同时具有执行权限的文件并备份到/data/backup/目录下。
find / -name *txt -mtime +30 -type f -size +20k -perm a=x -exec cp {}
/data/backup/ ;

当前test.txt所属的用户为root,组为abc,请将test.txt使拥有者为abc,组为root,写出命令。 chown
abc:root test.txt

每次开机在/tmp目录下创建一个当天的日期文件夹(提示:当前日期表示的方法为:date +%Y%m%d) echo “mkdir
/tmp/date +%Y%m%d” >> /etc/rc.d/rc.local

将普通用户test加入root组的命令是? usermod -G root test

ps: -aux, - ef:显示所有进程的相关信息,-ef是按照bsd版本的格式显示出来

top: top -p:显示指定的进程号的进程信息 top -S:以累积模式显示程序运行的时间

TCP为什要进行三次握手

如果采用两次的话,会出现下面这种情况。比如是A机要连到B机,结果发送的连接信息由于某种原因没有到达B机;于是,A机又发了一次,结果这次B收到了,于是就发信息回来,两机就连接。传完东西后,断开。
结果这时候,原先没有到达的连接信息突然又传到了B机,于是B机发信息给A,然后B机就以为和A连上了,这个时候B机就在等待A传东西过去。但是实际上此时A没有数据要传输,造成服务器事件白白的被浪费了。

TRUNCATE,DELETE,DROP比较:

TRUNCATE TABLE:删除内容、释放空间但不删除定义。 DELETE TABLE:删除内容不删除定义,不释放空间。 DROP
TABLE:删除内容和定义,释放空间。 速度: drop> truncate > delete。

长连接和短连接

连接->传输数据->关闭连接,短连接是指SOCKET连接后,发送接收完数据后马上断开连接。
因为连接后接收了数据就断开了,所以每次数据接受处理不会有联系。这也是HTTP协议无状态的原因之一。 连接->传输数据->保持连接 ->
传输数据->…………->直到一方关闭连接,多是客户端关闭连接。长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。
什么时候用长连接,短连接:
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,而且频繁的socket创建也是对资源的浪费。
比如说qq的维持在线显示状态使用的好像就是长连接,或者是网络游戏这样的,smtp,pop3,telnet这种就可以认为是长连接。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。比如百度的搜索服务,搜索完成之后建立的连接就会断开。

事件与消息的区别

事件是一个动作——用户触发的动作,消息是一个信息——传递给系统的信息。 事件:只能由用户的操作产生
消息:由操作系统产生。由用户触发的事件转换而来。由另一个消息产生。

Struct与Union之间的区别

结构体每个属性都可以有默认值,union只能有一个有默认值

Linux中进程调度方法

SCHED_OTHER: 分时调度方法
SCHED_FIFO: 先来先服务调度算法
SCHED_RR: 实时调度策略,采用的是时间片轮转

什么叫做MVC

    模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

    Model(模型)表示应用程序核心(比如数据库记录列表).View(视图)显示数据(数据库记录).Controller(控制器)处理输入(写入数据库记录)

    MVC分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。MVC分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。

static关键字在c++作用

文件中作用:作用域
函数中作用:长生存期,保持值
类中作用:类变量或者类函数,没有this指针,变量需要在外部初始化,否则链接错误,static可以用作callback 默认初始化值为0

IPCS命令

unix/linux下的共享内存、信号量、队列信息管理
在unix/linux下,经常有因为共享内存、信号量,队列等共享信息没有干净地清楚而引起一些问题。 查看共享信息的内存的命令是ipcs [-m|-s|-q]。

进程和线程的简单比较

进程是分配资源的基本单位(CPU、内存等),有独立的地址空间。线程是进程中的一个实体,共享进程的地址空间,是轻量级的进程,是CPU调度和分配的基本单位,但是各个线程拥有自己的栈空间。
(1)单线程遇到阻塞,会卡死,影响交互;
(2)发挥多核CPU的计算能力;
(3)简化程序结构,使程序便于维护;
(4)与进程相比,线程的创建和切换开销更小

Linux下进程通信的几种方式

(1)管道:具有亲缘关系的进程通信,命名管道允许无亲缘关系的进程通信,shell命令中的”|”就是一种管道通信,一个命令的输出作为另外一个进程的输入;
(2)信号:程序运行过程中可以随时被各种信号打断,从而去处理信号,Linux下面的kill命令就是通过信号的方式和其它进程通信,比如kill -l可以查看信号的分类,kill -9强制杀死对应进程;
(3)消息队列:有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点;
(4)共享内存:非常快的进程通信方式,和信号量结合起来,达到进程间的同步与互斥;
(5)socket:套接字可以让不同主机之间的进程进行通信,肯定还会讲到,很重要。

线程之间同步的方式

因为线程之间共享内存,所以线程之间需要进行同步。

同步的方式有互斥锁、条件变量、读写锁。

互斥锁用于保护临界区,信号量同理(注意和信号之间的区别);

条件变量用于发送信号和等待信号;

读写锁是在互斥锁的基础上做的改进,又被成为共享-独占,非常适合于读数据的频率远大于写数据的频率的应用。

数据库常用的优化技巧

(1)索引:优点是读速度快;带来的缺点是体积变大、插入性能变差(需要创建索引);
(2)缓存配置(缓存查询语句,缓存查询数据);
(3)分库分表,分表又分为垂直和水平拆分;
(4)子查询优化。

epoll的ET模式与LT模式

    对LT模式。epoll_wait检测到其上有事件发生并且将此事件通知应用的时候,应用程序可以不立即处理,那么下一次调用epoll_wait的时候,epoll_wait还是会将这个时间通知上层应用。直到这个时间被处理。对LT模式。当epoll_wait第一次通知上层这个事件的时候,应用程序必须立即处理,因为后续epoll_wait不会再向上层通知这个事件。epoll再很大程度上降低了同一个事件被多次触发的概率EPOOL如果触发一个线程开始读取socket上的一个事件的时候,在数据处理的过程中这个socket可能又有新的数据到来,epoll可能触发另一个线程来处理,如果期望一个socket在任意时刻只能被一个线程处理的话,那么可以是使用epoll的EPOLLONESHOT来实现。当然了,当一个线程处理完成了注册了EPOLLONESHOT的socket上的时间之后,需要立即将EPOLLONESHOT重置,这样才能让socket的后续事件得到处理。

例如下面这样

void reset(int epollfd, int fd){
    epoll_event event;
    event.data.fd = fd;
    event.events = EPOLLIN | EPOLLET | EPOLLONESHUT;
    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event);
}

非阻塞的connect
对非阻塞的socket调用connect,而连接又没有建立的时候,会返回EINPROGRESS(表示连接还正在进行),这时可以使用epoll监听这个连接失败socket上的可读可写事件。epoll返回的时候,再用getsockopt清除这个socket上的错误,错误码为0的话代表简历连接成功否则表明建立连接失败。
关于Unicode
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字”严”。
但是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。比如,汉字”严”的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多的字节也是有可能的。
UTF-8是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------±--------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1
2
3
4
5
6
7
跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
下面,还是以汉字”严”为例,演示如何实现UTF-8编码。
已知”严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx 10xxxxxx 10xxxxxx”。然后,从”严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,”严”的UTF-8编码是”11100100 10111000 10100101”,转换成十六进制就是E4B8A5。
字符编码笔记:ASCII,Unicode和UTF-8
伙伴算法和slab分配器以及vmalloc
Linux使用伙伴算法来进行内存的分配(现代操作系统434),但是其会导致内存碎片,比如需要65页面大小的块,那么必须要申请到128页面的块。也就是内存分配会按照2^n的情况来进行划分
缓解这个问题Linux使用的是slab分配器。其使用伙伴算法分配内存,但是切分成更加细化的块来进行管理。其基本思想是:一次向内核获取整数页,slab根据数据结构的大小进行划分为一个个小的数据结构,当需要时直接从该链表上摘取一个返回应用程序,当应用程序释放时,而非真正释放,只需要该空间放回到链表中,当分散的一页多块又聚集一页时,又会拼成一页,同时判断slab空闲的页数,如果空闲页超过一定的页数,就会向系统释放一定的页数。一个slab分配器只能管理一个指定大小的数据结构分配。
一个slab分配器管理许多页,而每一页又管理许多的对象。为了有效管理页,即便于分配与释放,又根据页内对象的数量将页分为3个状态:
空闲(free)状态:该页没有分配出去任何对象
部分分配(partial)状态:该页只有部分对象被分配
完全分配(full)状态:该页所有对象都被分配出去。
vmalloc用于仅仅需要虚拟地址空间连续的请求,常用于动态的插入内核模块。
Slab以及Buddy算法之间的区别
Slab分配器概述
Slab分配器
TCP的拥塞避免算法
慢开始:在主机刚刚开始发送报文段时可先将拥塞窗口cwnd设置为一个最大报文段MSS的数值。在每收到一个对新的报文段的确认后,将拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送端的拥塞窗口cwnd,可以分组注入到网络的速率更加合理。
拥塞避免:当拥塞窗口值大于慢开始门限时,停止使用慢开始算法而改用拥塞避免算法。拥塞避免算法使发送的拥塞窗口每经过一个往返时延RTT就增加一个MSS的大小。
快重传算法规定:发送端只要一连收到三个重复的ACK即可断定有分组丢失了,就应该立即重传丢手的报文段而不必继续等待为该报文段设置的重传计时器的超时。
快恢复算法:当发送端收到连续三个重复的ACK时,就重新设置慢开始门限 ssthresh与慢开始不同之处是拥塞窗口 cwnd 不是设置为 1,而是设置为ssthresh,
若收到的重复的AVK为n个(n>3),则将cwnd设置为ssthresh
若发送窗口值还容许发送报文段,就按拥塞避免算法继续发送报文段。
若收到了确认新的报文段的ACK,就将cwnd缩小到ssthresh
乘法减小:是指不论在慢开始阶段还是拥塞避免阶段,只要出现一次超时(即出现一次网络拥塞),就把慢开始门限值 ssthresh 设置为当前的拥塞窗口值乘以 0.5。当网络频繁出现拥塞时,ssthresh 值就下降得很快,以大大减少注入到网络中的分组数。
加法增大:是指执行拥塞避免算法后,在收到对所有报文段的确认后(即经过一个往返时间),就把拥塞窗口 cwnd增加一个 MSS 大小,使拥塞窗口缓慢增大,以防止网络过早出现拥塞。
拥塞避免算法小结
LinuxC小结
linux c 小结

对云的理解
计算、存储能力虚拟化。可以把云计算想象成一种电,一种从“发电厂”自由流动的信息流,我们需要的只是一个接入这种流的端口,所有的个人PC都不再需要了就像不需要发电机一样。如果云计算像电能一样普及,那我们看到的可能真的就是和黑客帝国里面的世界一样,信息流在世界流动,驱动各种设备运转,人工智能,虚拟现实都在这个基础上实现。而且电能的普及也经过了从独立发电到集中供电的这样一个过程,是不是很像今天的云计算,先是各个企业建立自己的数据中心,后来发现自己维护数据中心过于昂贵于是购买专业的云服务。事物的发展何其相似。
DDos攻击
过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的。 这种攻击方式可分为以下几种:
通过使网络过载来干扰甚至阻断正常的网络通讯;
通过向服务器提交大量请求,使服务器超负荷;
阻断某一用户访问服务器;
阻断某服务与特定系统或个人的通讯。
单例的double check的问题
public static Singleton getInstance() {
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
1
2
3
4
5
6
7
8
9
10
上面这种单例的问题在于,优先高级语言的new 以及赋值是分开的。也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就可能出错了,我们以A、B两个线程为例:
A、B线程同时进入了第一个if判断
A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();
由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。
B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
可以使用一个内部类来克服double check的缺点:
public class Singleton {

private Singleton() {
}


private static class SingletonFactory {
    private static Singleton instance = new Singleton();
}


public static Singleton getInstance() {
    return SingletonFactory.instance;
}


public Object readResolve() {
    return getInstance();
}

}

常见的数据库对象

表:基本的数据存储集合,由行和列组成。
视图:从表中抽出的逻辑上相关的数据集合。
序列:提供有规律的数值。
索引:提高查询的效率
同义词 :给对象起别名

数据库约束

NOT NULL,UNIQUE ,PRIMARY KEY,FOREIGN KEY,CHECK列级约束只能作用在一个列上,而表约束可以作用在多个列上(当然表约束也可以作用在一个列上)。列约束必须跟在列的定义里后面,表约束不与列一起,而是单独定义。非空(not null) 约束只能定义在列上

例:添加一个外键约束:

ALTER TABLE     employees
ADD ConSTRAINT  emp_manager_fk 
FOREIGN KEY(manager_id) 
REFERENCES employees(employee_id);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/766848.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号