这篇文章是leetcode刷题系列的第3部分——字符串。这里把有代表性的题目发出来,共计21道。字符串的问题杂且难,这一块,面试时碰到字符串问题时只能随机应变,没有固定的套路。
leetcode刷题系列其它文章组织如下:
1. 数组
2. 链表
3. 字符串
4. 二叉树
5. 队列和栈
6. 动态规划
7. 数据结构设计
8. 刷题小知识点
前两天在牛客网做了模拟笔试题,有两道感觉挺有意思的,这里总结一下。其中一道题稍微修改了点条件,进阶一下。
特么的我都不想说,其实这修改的条件是我笔试时没读清题,直接往难了去想的,就没做出来(呜呜呜,哭晕在厕所)。以后做题一定要审清题啊!!!
IPC对象
内核中用于进程间通信的数据结构,全局可见,如消息队列的msg_queue结构体、信号量的sem_array结构体,共享内存的shmid_kernel结构体。类似于普通文件是通过文件名(文件描述符)进行读写操作,通过IPC key和IPC标识符进行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标识符,否则,就返回一个错误码。
先来了解一些背景知识。
进程地址空间的组成:
BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。是可读写的。在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了)。 data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。 code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。 heap)是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free函数释放内存时,被释放的内存从堆中被释放(堆被缩减) 。stack)又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数块中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。malloc分配的大块内存区域(大于128K)。操作系统将内存分为两部分:一部分供操作系统使用(驻留内核进程和重要的数据结构等),另一部分供用户进程使用,必须将内存进一步的细分给不同的用户进程以满足多个进程的需求。操作系统完成这一“细分”的任务的过程就叫做内存管理。