1.进程与线程
进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值。
线程被设计成进程的一个执行路径,同一个进程中的线程共享进程的资源
本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
- 进程阻塞的原因:进程sleep、等待解锁、等待I/O;
- 时间片用完,进程进入就绪态
进程的五种状态为创建、就绪、阻塞、执行、终止;其中工作状态为就绪、阻塞、执行
2.虚拟内存会用硬盘中的一部分存储空间当做内存
虚拟内存隔离了各个进程内存空间。虚拟内存使每个进程都感觉自己拥有一块连续的内存空间,而不需要了解其他进程的内存布局,从而提供了进程间的间隔
虚拟内存可以防止应用程序直接访问物理地址,虚拟内存将应用程序看到的内存地址与物理内存地址分离开来,应用程序访问的是虚拟地址,而不是直接访问物理地址,从而增强了系统的安全性和稳定性。
3.算法指的是:解决问题的有限运算序列
算法的基本要素包括 对数据对象的运算和操作、算法的控制结构
4.递归函数调用有开销,递归的次数受堆栈大小的限制,非递归效率更高
5.Tcp/IP协议共分为四层,应用层主要是FTP,HTTP,DNS;传输层主要是TCP,UDP;网络层有ICMP,ARP,PARP;数据链路层主要是网络接口和硬件层。
四层是指网络的传输层,主要包括IP和端口信息,代理TCP、UDP
七层是指网络的应用层,比如HTTP协议就在七层、SNMP
网络端口:端口范围受限于系统的文件句柄数量
6.操作系统采用缓冲技术:1.可以减少对cpu的中断次数2.减少cpu与I/O设备间速度不匹配的矛盾3.提高cpu和I/O设备间的并行性
7.进程间通信:1.管道2.信号3.信号量4.共享通信5.socket6.消息队列
8.>定向到文件 chmod 设置文件权限 tail查看文件或目录
9.堆栈溢出:1.循环的递归调用2.大数据的局部变量3.无限循环 4.大规模数据处理
10.逻辑结构分为:1.集合结构2.线性结构3.树型结构4.图形结构
11.子查询:嵌套到另一个查询语句之中的查询语句
索引对数据库的插入效率有一定影响;可以在多个列上建立联合索引;对于数据重复度高,值范围有限的列如果建立索引建议使用位图索引
12.get请求的参数在url中,post请求的参数在消息主体中
13.具有风险分析的软件生命周期模型是螺旋模型
14.代码题
问题描述:请实现一个函数,把字符串中的每个空格替换成"%20"。要求用C/C++语言实现,而且时间复杂度为O(n)。输入描述:输入一个字符串,把字符串中的空格,都替换成"%20"输出描述:输出替换完成的字符串输入样例:I love Xiaomi输出样例:I$20love820xiaomi
#include <stdio.h>
#include <string.h>
// 假设result有足够的空间来存储替换后的字符串
void replaceSpaces(char *s, char *result, int resultSize) {
int i = 0, j = 0;
while (s[i] != '\0' && j < resultSize - 1) { // 确保不会超出result的大小
if (s[i] == ' ') {
result[j++] = '%';
result[j++] = '2';
result[j++] = '0';
} else {
result[j++] = s[i];
}
i++;
}
result[j] = '\0'; // 添加字符串结束符
}
int main() {
char s[] = "I love Xiaomi";
// 假设我们知道替换后的最大长度(这里简单估算为原长度的两倍加1)
char result[100]; // 实际上,应该根据s的长度动态计算result的大小
replaceSpaces(s, result, sizeof(result));
printf("%s\n", result);
return 0;
}
15.问题描述:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的输入描述:输入两个有序递增列表输出描述:输出合并的有序递增列表输入样例:1 6 12 18 3 5 9 20
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
struct ListNode {
int val;
struct ListNode *next;
};
// 创建一个新的链表节点
struct ListNode* createNode(int val) {
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
if (!newNode) return NULL;
newNode->val = val;
newNode->next = NULL;
return newNode;
}
// 合并两个有序链表
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
// 创建一个哨兵节点,简化边界处理
struct ListNode dummy;
dummy.next = NULL;
struct ListNode* tail = &dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->val < l2->val) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail = tail->next;
}
// 处理剩余的元素
if (l1 != NULL) {
tail->next = l1;
}
if (l2 != NULL) {
tail->next = l2;
}
return dummy.next;
}
// 打印链表
void printList(struct ListNode* head) {
while (head != NULL) {
printf("%d ", head->val);
head = head->next;
}
printf("\n");
}
// 辅助函数,用于构建链表
struct ListNode* buildList(int* nums, int numsSize) {
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
for (int i = 0; i < numsSize; i++) {
struct ListNode* newNode = createNode(nums[i]);
if (head == NULL) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
}
return head;
}
int main() {
int nums1[] = {1, 6, 12, 18};
int nums2[] = {3, 5, 9, 20};
int numsSize1 = sizeof(nums1) / sizeof(nums1[0]);
int numsSize2 = sizeof(nums2) / sizeof(nums2[0]);
struct ListNode* list1 = buildList(nums1, numsSize1);
struct ListNode* list2 = buildList(nums2, numsSize2);
struct ListNode* mergedList = mergeTwoLists(list1, list2);
printList(mergedList);
// 注意:在实际应用中,需要释放链表占用的内存
return 0;
}
- 视图是基于数据库的查询窗口。不能在这种查询窗口中再见数据表。
从数据库系统外部看,一个视图是由select语句组成的查询定义的虚拟表。视图就如同一张表一样,视图可以查询,但不能新增删除修改。
从数据库系统内部看,视图由一张或者多张表中的数据组成。
- Undefined == null;parselnt(“1a”)== 1; []instanceof Array
- Slice()从已有的数组中返回选定的元素,不改变原数组,返回一个新数组
- Concat()连接两个或多个数组,不改变原数组,返回被连接数组的一个副本
- Splice()从数组中添加/删除项目,改变原数组,返回被删除的元素
- 同步消息是调用者发出消息后,必须等待消息处理结束返回后,才能进行后续操作
- 返回消息,不属于消息类型
- 异步消息是指调用者发送的消息不需要立即等待返回结果,而可以继续执行其他任务,等到被调用方处理完毕再异步返回结果给调用者
- 简单消息,没有一个明确的概念与之对应
- 计算优先级最高的 是基本路径覆盖法。确保所有可能的路径都被至少执行一次,以尽可能地发现潜在问题。这种方式通常被认为是测试覆盖率的高级别
冒泡排序、选择排序、插入排序时间复杂度是O(n^2)