0%

这篇文章是leetcode刷题系列的第3部分——字符串。这里把有代表性的题目发出来,共计21道。字符串的问题杂且难,这一块,面试时碰到字符串问题时只能随机应变,没有固定的套路。

leetcode刷题系列其它文章组织如下:

1. 数组

2. 链表

3. 字符串

4. 二叉树

5. 队列和栈

6. 动态规划

7. 数据结构设计

8. 刷题小知识点

阅读全文 »

这篇文章是leetcode刷题系列的第6部分——动态规划。这里把有代表性的题目发出来,共计56道。动态规划题目变化多端,目前旨在于习得通用的解题技巧,这些只是比较经典的动态规划题目。

leetcode刷题系列其它文章组织如下:

1. 数组

2. 链表

3. 字符串

4. 二叉树

5. 队列和栈

6. 动态规划

7. 数据结构设计

8. 刷题小知识点

阅读全文 »

前两天在牛客网做了模拟笔试题,有两道感觉挺有意思的,这里总结一下。其中一道题稍微修改了点条件,进阶一下。

特么的我都不想说,其实这修改的条件是我笔试时没读清题,直接往难了去想的,就没做出来(呜呜呜,哭晕在厕所)。以后做题一定要审清题啊!!!

阅读全文 »

这篇文章是leetcode刷题系列的第1部分——数组。这里把有代表性的题目发出来,共计82道。主要涉及滑动窗口、哈希表、堆、二分搜索、扫描线、区间相关、拓扑排序、树状数组等算法。

leetcode刷题系列其它文章组织如下:

1. 数组

2. 链表

3. 字符串

4. 二叉树

5. 队列和栈

6. 动态规划

7. 数据结构设计

8. 刷题小知识点

阅读全文 »

什么是僵尸进程?

简单的说,僵尸进程就是子进程先于父进程退出,并且父进程并没有调用wait系统调用,即使其进程映像中占用的系统资源(比如内存,页表等)都会被释放回收,但这时子进程的进程描述符(PCB)结构仍然存在于系统中得不到释放,就称这样的进程为僵尸进程(Zombie)。

阅读全文 »

背景知识

  • IPC对象

    内核中用于进程间通信的数据结构,全局可见,如消息队列的msg_queue结构体、信号量的sem_array结构体,共享内存的shmid_kernel结构体。类似于普通文件是通过文件名(文件描述符)进行读写操作,通过IPC keyIPC标识符进行IPC对象的读写操作。

  • IPC标识符ID

    类似于文件描述符fd,可以用一个IPC标识符来引用一个IPC对象,是一个32位整数,是IPC对象的外部名字。返回给用户进程的。

  • IPC key(魔数)
    IPC对象的内部名,是一个独一无二的整数,用来确保IPC对象的唯一性。该整数类型为key_t,在sys/types.h中被定义为长整型。
    类似于普通文件通过文件名open一个文件,获得文件描述符;IPC对象是get函数根据给定的key去创建一个IPC对象,并返回IPC标识符ID。根据新资源是信号量、消息队列还是共享内存,分别调用semget()msgget()或者shmget()函数创建IPC资源。

    这三个函数的主要目的都是从IPC key(作为第一个参数传递)中导出相应的IPC标识符ID,进程以后就可以使用这个标识符对资源进行访问。如果还没有IPC资源和IPC关键字相关联,就创建一个新的资源。如果一切都顺利,那么函数就返回一个正的IPC标识符,否则,就返回一个错误码。

阅读全文 »

这篇文章是leetcode刷题系列的第5部分——队列和栈。这里把有代表性的题目发出来,共计22道。主要涉及BFS算法、DFS算法、单调栈以及单调队列技巧的应用。

leetcode刷题系列其它文章组织如下:

1. 数组

2. 链表

3. 字符串

4. 二叉树

5. 队列和栈

6. 动态规划

7. 数据结构设计

8. 刷题小知识点

阅读全文 »

先来了解一些背景知识。

进程地址空间的组成

  1. 内核空间:这块区域包含两种数据,一种是对每个进程都一样的数据,如共享的内核代码和全局数据结构。另一种是每个进程都不一样的数据,如页表、内核在进程上下文中执行代码时使用的栈,以及记录该进程虚拟地址空间当前组织状态的各种数据结构。
  2. BSSBlock Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。是可读写的。在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了)。
  3. 数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
  4. 代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
  5. 堆(heap)是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free函数释放内存时,被释放的内存从堆中被释放(堆被缩减) 。
  6. 栈(stack)又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数块中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
  7. 内存映射区:这块虚拟内存区域被映射到任何需要的对象身上,如共享库文件、磁盘上的普通文件和将要介绍的通过malloc分配的大块内存区域(大于128K)。
阅读全文 »

操作系统将内存分为两部分:一部分供操作系统使用(驻留内核进程和重要的数据结构等),另一部分供用户进程使用,必须将内存进一步的细分给不同的用户进程以满足多个进程的需求。操作系统完成这一“细分”的任务的过程就叫做内存管理

阅读全文 »

并发的概念

在单处理器多道程序设计系统中,进程会被交替地执行,因而表现出一种并发执行的外部特征。支持并发进程的基本需求是加强互斥的能力。也就是说,当一个进程被授予互斥能力时,那么在其活动期间,它具有排斥所有其他进程的能力。

并发包括很多设计问题,其中有进程间通信、资源共享与竞争(如内存、文件、I/O访问)、多个进程活动的同步以及给进程分配处理器时间等。并发问题源于多道程序设计系统的一个基本特性:进程的相对执行速度不可预测,它取决于其他进程的活动、操作系统处理中断的方式以及操作系统的调度策略。

阅读全文 »