1. 僵尸进程
僵尸进程(Zombie Process)在操作系统中指的是那些已经执行完毕,但其父进程尚未对其进行善后处理(例如读取子进程的状态信息或者执行回收资源的操作)的进程。在Unix和类Unix系统(比如Linux)中,当一个进程结束运行后,它的进程控制块(PCB,包含了进程的状态信息)仍然保留在系统中,直到父进程通过`wait()`系统调用对其进行处理。如果父进程没有调用`wait()`,那么结束的进程就会变成僵尸进程。
僵尸进程是无害的,因为它们实际上并不占用除了进程表项之外的任何资源,也不会执行任何代码。然而,僵尸进程在进程表中占据了一个位置,而大量的僵尸进程可能会消耗所有的进程号,防止新的进程被创建。
在编写多进程程序时,合理管理子进程的生命周期和状态是非常重要的,以避免产生僵尸进程。
2. 修改文件权限
在Linux系统中,修改文件权限通常使用`chmod`(change mode)命令。这个命令可以通过字母表示法(u表示用户,g表示组,o表示其他人,a表示所有人)或者八进制数表示法来指定权限。
这是一些例子:
//给所有者增加执行权限:
chmod u+x 文件名
//给组增加读写权限:
chmod g+rw 文件名
//给其他用户去除所有权限:
chmod o-rwx 文件名
//给所有用户设置读和执行权限:
chmod a+rx 文件名
//只给所有者设置读写执行权限,而给组和其他用户设置读权限:
chmod u=rwx,g=r,o=r 文件名
例如:
//设置所有者读写执行(7),组读执行(5),其他用户执行(1):
chmod 751 文件名
//设置所有者读写(6),组读(4),其他用户无权限(0):
chmod 640 文件名
//设置所有人都有读写执行权限:
chmod 777 文件名
//设置所有人都有读写权限:
chmod 666 文件名
在使用`chmod`命令时,还可以加上`-R`选项递归地修改目录及其子目录中的所有文件和目录的权限:
chmod -R 755 目录名
在修改文件权限之前,你需要确保有足够的权限去改变这些文件的权限,通常需要文件的所有者或者是root用户才能修改权限。
3. 修改用户组
在Linux中,您可以使用各种命令来修改用户组。以下是一些常用的命令和步骤:
1. 更改用户的主要组:
使用`usermod`命令加上`-g`选项来更改用户的主要组:
sudo usermod -g 新主要组 用户名
这将改变用户的主要组。请注意,这可能会影响用户对文件的默认访问权限,因为Linux系统中的文件通常会继承其所有者的主要组。
2.添加用户到附加组:
使用`usermod`命令加上`-aG`选项来将用户添加到一个或多个附加组:
sudo usermod -aG 组名1,组名2,... 用户名
使用 `-a` 选项是非常重要的,因为它表示追加用户到新组而不会从用户目前所属的其他组中移除。
3. 创建新用户组:
如果需要的话,可以先创建一个新的用户组:
sudo groupadd 新组名
4.更改文件或目录的组:
使用`chown`命令来更改文件或目录的组:
sudo chown :新组名 文件或目录
请注意,前面的冒号是必需的,这表明您正在更改组而不是所有者。
5. 更改用户的登录组:
如果您需要更改用户登录时所属的组,可以使用`newgrp`命令:
newgrp 新组名
这个命令会启动一个新的shell会话,并且在这个会话中用户的主要组会被更改为指定的新组。
6. 查看用户所属的组:
如果您想要确认用户的组修改操作是否成功,可以使用以下命令:
groups 用户名
或者:
id 用户名
4. deb编包机制 linux学习系列——编包_传统的launchpad,是把代码下载到本地,然后执行debuild -s -sa在本地生成一个 包-CSDN博客
5. cmake作用
CMake是一个跨平台的自动化构建系统,主要用于管理软件构建的过程,它使用平台和编译器独立的配置文件来生成标准的构建文件,使得你可以在多种系统上以统一的方式构建你的项目。
6. makefile作用
`Makefile` 是一个特殊的文件,用于存储编译和链接程序的命令。这个文件被 `make` 工具读取和解析,用于自动化构建过程。`make` 工具检查文件的依赖关系,并执行 `Makefile` 中定义的命令来编译源代码并构建目标程序或库。
总而言之,`Makefile` 提供了一种灵活、强大的方式来管理和控制编译过程。通过简单的 `make` 命令,开发者可以执行复杂的构建任务,而无需记住繁琐的编译指令和链接参数。
二者区别(自己加的,面试没问)
简单来说,CMake 是一个构建系统生成器,它可以根据你的项目配置生成 Makefile 或其他构建系统文件;而 Makefile 是一个构建脚本,包含了具体的构建命令,由 `make` 工具直接执行。CMake 的抽象级别更高,更易于跨平台使用和维护,而 Makefile 给予开发者更底层的控制,但可能需要针对不同平台进行手动调整。
7. 软连接硬链接
在Unix-like操作系统中,软链接(Symbolic Link)和硬链接(Hard Link)是两种不同类型的文件系统链接:
总结一下,硬链接像是一个文件的额外别名,它和原始文件在文件系统中完全平等,不存在主次之分。而软链接更像是一个指向另一个文件或目录的指针,它依赖于原始文件或目录的路径。硬链接通常用于保证文件即使被删除也能被访问,而软链接用于创建实际文件位置的引用,更加灵活,但当原始文件被移动或删除时,链接将会失效。
8. 类模板和函数模板
类模板和函数模板-CSDN博客
9. 多态
虚函数的疑问-CSDN博客
10. static成员函数变量作用,为什么定义为static
c++中static的作用-CSDN博客
11. 深拷贝浅拷贝、代码
在 C++ 中,深拷贝和浅拷贝是在进行对象复制时的两种不同方式。深拷贝会复制对象的所有成员,包括指向的动态内存,而浅拷贝只是简单地复制对象的成员变量值,而不会复制指向的动态内存。下面是一个简单的示例代码,演示深拷贝和浅拷贝的区别:
#include
#include // 用于字符串操作
class DeepCopyExample {
public:
char* data; // 使用指针来模拟动态内存
// 构造函数
DeepCopyExample(const char* str) {
data = new char[strlen(str) + 1]; // 为 data 分配内存
strcpy(data, str); // 复制字符串内容
}
// 深拷贝构造函数
DeepCopyExample(const DeepCopyExample& other) {
data = new char[strlen(other.data) + 1]; // 为 data 分配内存
strcpy(data, other.data); // 复制字符串内容
}
// 析构函数
~DeepCopyExample() {
delete[] data; // 释放动态内存
}
};
int main() {
DeepCopyExample obj1("Hello");
DeepCopyExample obj2 = obj1; // 调用深拷贝构造函数
std::cout << "obj1 data: " << obj1.data << std::endl;
std::cout << "obj2 data: " << obj2.data << std::endl;
// 修改 obj2 的 data
obj2.data[0] = 'C';
std::cout << "After modifying obj2 data:" << std::endl;
std::cout << "obj1 data: " << obj1.data << std::endl;
std::cout << "obj2 data: " << obj2.data << std::endl;
return 0;
}
在这个示例中,`DeepCopyExample` 类包含一个 `char*` 类型的成员变量 `data`,用于模拟动态分配的内存。在构造函数中,我们为 `data` 分配内存并复制字符串内容。在深拷贝构造函数中,我们为新对象的 `data` 再次分配内存并复制内容,从而实现深拷贝。
在 `main` 函数中,我们创建了两个对象 `obj1` 和 `obj2`,并通过深拷贝构造函数将 `obj1` 的内容复制给 `obj2`。然后我们修改了 `obj2` 的 `data`,但不会影响到 `obj1` 的 `data`,因为它们分别拥有独立的内存空间。
12. 智能指针,智能指针怎么释放的资源
智能指针就是利用了 RAII 技术来实现自动管理资源的机制。通过智能指针,我们可以更方便地管理动态分配的内存、文件流、数据库连接等资源,避免内存泄漏和资源泄露。
当使用智能指针时,智能指针对象会在它们超出作用域时自动调用析构函数,从而释放所管理的资源。这种自动释放资源的机制大大简化了资源管理的工作,减少了程序出错的可能性。
智能指针的不同类型(如 `std::unique_ptr`、`std::shared_ptr`、`std::weak_ptr`)会根据自身的特性来管理资源的生命周期,例如 `std::unique_ptr` 独占所有权、`std::shared_ptr` 共享所有权等。但它们都依赖于 RAII 技术来实现资源的自动释放。
自动释放资源的机制是通过 RAII(资源获取即初始化)技术来实现的。RAII 是 C++ 中的一种编程范式,它利用对象的生命周期与作用域的关系,来确保在对象生命周期结束时自动执行资源的获取和释放操作。
在 C++ 中,当一个对象在其作用域结束时,其析构函数会被自动调用,从而实现资源的自动释放。这种特性被广泛运用在智能指针、文件流、数据库连接等资源管理场景中,帮助开发者避免内存泄漏和资源泄露的问题。下面是一个简单的示例来说明 RAII 的自动释放资源机制:
#include
class Resource {
public:
Resource() {
std::cout << "Resource allocated" << std::endl;
}
~Resource() {
std::cout << "Resource released" << std::endl;
}
void doSomething() {
std::cout << "Resource being used" << std::endl;
}
};
int main() {
{
Resource res; // 在作用域内创建 Resource 对象
// 使用 Resource 对象
res.doSomething();
} // Resource 对象超出作用域,自动调用析构函数释放资源
return 0;
}
在上面的示例中,当 `Resource` 对象 `res` 超出作用域时,它的析构函数会被自动调用,输出 `"Resource released"`,从而释放资源。这种自动释放资源的机制使得我们不再需要手动管理资源的释放,减少了出错的可能性。
13. 动态库 静态库
动态库和静态库是在软件开发中常用的两种库文件形式,它们都是用来存放可重用的代码和函数的。下面我将简单介绍一下动态库和静态库的概念以及它们之间的区别:
14. 查看进程id
ps命令
15. 如何关注进程状态
ps aux