• 22-9-17学习笔记


    四次挥手状态

     

    什么是系统调用

    进程在系统上运行级别分为用户态和内核态,处于用户态的进程需要使用操作系统的功能,需要进行系统调用,切换成内核态调用操作系统的核心功能。

    死锁的四个条件

    互斥,持有并等待,非抢占,等待成环

    解除死锁的四个方案

    预防(资源分层),避免(银行家算法),检测(资源图),解除

    内存管理机制

    块式管理,分页管理,分段管理

    分页管理和分段管理的区别

    相同点:为了提高内存的利用率,较少碎片,页之间和段之间是不连续的,但是内部是连续的。

    不同点:也的大小是固定的,由操作系统决定,但段的大小不固定。

    Linux环境变量

    用户级:~/.bashrc,~/.bashrc_profile

    系统级:/etc/bashrc/etc/environment/etc/profile/etc/profile.d

    环境生效的优先级:/etc/enviroment –> /etc/profile –> /etc/profile.d –> ~/.bash_profile –> /etc/bashrc –> ~/.bashrc

    一般用户级的环境在~/.bashrc_profile,系统环境变量一般在/etc/profile.d中设置。

    Linux查看性能指标常用的命令

    查看网络吞吐率,sar -n TCP 秒,表示每秒统计tcp连接数

    为什么存在DMA?

    DMA之间的IO流程:1,cpu向磁盘控制器发送消息表示要进行读数据。2,磁盘控制器准备好数据,向cpu发送中断请求。3,cpu会将磁盘控制器缓存中的数据一个字节一个字节传输到磁盘缓冲中。4,cpu再将磁盘缓冲中的数据拷贝到用户缓冲区中。5,在3,4阶段,cpu不能处理其他事情。

    DMA流程:原理:IO设备和内存之间的数据传输不需要CPU参与。1,cpu向DMA发送消息,DMA向磁盘发送消息。2,磁盘控制器准备好数据,反馈给DMA控制器。3,DMA控制器将磁盘控制器缓冲区的数据传输到磁盘缓冲区。4,DMA通知CPU,cpu将数据从内核拷贝到用户缓冲区。

    传统的文件传输的流程

    文字描述:传统的文件传输要经过用户态和内核态之间的来回拷贝,消耗较大。从磁盘中读取数据并通过网卡发送出去为例:1,通过DMA将磁盘控制器的缓冲区中拷贝到内核态的缓冲区(磁盘缓冲区)。2,从内核态的缓冲区拷贝到用户态的缓冲区。3,将用户态的缓冲区拷贝到内核态缓冲区(Socket缓冲区)。4,通过DMA将数据拷贝到网卡。

    如何实现零拷贝

    如何提高文件传输的效率,较少拷贝的次数、减少内核态和用户态切换的次数。

    1,mmap+write,mmap可以做到用户态缓冲区和内核态缓冲的数据的一个映射,可以避免了数据从内核态拷贝到用户态。流程:1,DMA将数据从磁盘控制器缓冲区拷贝的内核区。2,write操作直接将数据从磁盘缓冲区拷贝到socket缓冲区(内核态之间的数据拷贝)。3,通过DMA将数据从socket缓冲区发送到网卡。但是还是会有四次状态的切换,还会有内核态到用户态的变化。

    2,sendfile:直接将磁盘缓冲区的数据通过CPU拷贝到socket缓冲区,不存在内核态和用户态之间的切换。

    3,the-scatter-gather-DMA,直接可以认为数据从磁盘缓冲区通过DMA发送到网卡,sokcet缓冲会收到一些小字段的描述符。

    磁盘缓冲区

    磁盘缓冲区是位于内存中,存储着磁盘中部分数据,有缓存最近的数据和预读的功能。

    (直接IO)大文件传输需要禁用磁盘缓冲区,避免浪费一次的DMA传输和抢占磁盘缓冲区的热点位置。

    IO多路复用

    select:调用select,会将slect监听的文件描述符集合从用户态拷贝到内核态,由内核态遍历判断是否有事件的发生,当有事件的发生,文件描述符集合从内核态拷贝到用户态,用户态在进行遍历找到触发的事件,slect有监听文件的上线为1024.

    poll:和slect基本相同,但是监听的文件描述符的数量大于1024.

    epoll:有三个方法,epoll-create创建一个文件描述fd,epoll-ect将文件描述fd加入到内核中的红黑树中,当有事件发生的fd,会通过回调函数调入到就绪链表中。epoll-wait函数会返回所有的就绪fd。epoll分为水平模式和边缘模式,边缘模式是指调用一个epoll-wait方法,其对应的就绪文件描述符不进行处理的话,下次调用就不会返回,水平模式的话,第一次调用不进行处理的话,下次调用的时候还可以继续处理。

    常见的面试算法题

    两个线程轮流打印1-100

    1. public class Main {
    2. static int i = 0;
    3. public static void main(String[] args) {
    4. Object o = new Object();
    5. new Thread(()->{
    6. while(i<100){
    7. synchronized (o) {
    8. if((i&1) ==0){
    9. System.out.println(Thread.currentThread().getName()+":"+i);
    10. o.notify();
    11. i++;
    12. }else {
    13. try {
    14. o.wait();
    15. } catch (InterruptedException e) {
    16. e.printStackTrace();
    17. }
    18. }
    19. }
    20. }
    21. },"偶数线程").start();
    22. new Thread(()->{
    23. while(i<100){
    24. synchronized (o) {
    25. if((i&1) ==1){
    26. System.out.println(Thread.currentThread().getName()+":"+i);
    27. o.notify();
    28. i++;
    29. }else {
    30. try {
    31. o.wait();
    32. } catch (InterruptedException e) {
    33. e.printStackTrace();
    34. }
    35. }
    36. }
    37. }
    38. },"奇数线程").start();
    39. }
    40. }

    堆排序

    1. import java.util.Arrays;
    2. public class Main {
    3. static int i = 0;
    4. public static void main(String[] args) {
    5. int []nums = new int[]{1,3,5,7,9,0,2,4,6,8,10};
    6. heapSort(nums);
    7. System.out.println(Arrays.toString(nums));
    8. }
    9. public static void heapSort(int []nums){
    10. int len = nums.length;
    11. initHeap(nums,len);
    12. int index = len - 1;
    13. for (int i =0;i
    14. swap(nums,0,index);
    15. heapfying(nums,0,index);
    16. index --;
    17. }
    18. }
    19. private static void initHeap(int[] nums, int len) {
    20. for (int i = len / 2 - 1 ;i>=0;i--){
    21. heapfying(nums,i,len);
    22. }
    23. }
    24. private static void heapfying(int[] nums, int i, int len) {
    25. int left = 2 * i + 1;
    26. int right = 2 *i + 2;
    27. int max_index = i;
    28. if(left < len &&nums[left] > nums[max_index]){
    29. max_index = left;
    30. }
    31. if(right < len &&nums[right] > nums[max_index]){
    32. max_index = right;
    33. }
    34. if(i != max_index){
    35. swap(nums,i,max_index);
    36. heapfying(nums,max_index,len);
    37. }
    38. }
    39. private static void swap(int[] nums, int i, int j) {
    40. int tep = nums[i];
    41. nums[i] = nums[j];
    42. nums[j] = tep;
    43. }
    44. }

    快排序

    1. import java.util.Arrays;
    2. public class Main {
    3. static int i = 0;
    4. public static void main(String[] args) {
    5. int []nums = new int[]{1,3,5,7,9,0,2,4,6,8,10};
    6. quickSort(nums,0,nums.length-1);
    7. System.out.println(Arrays.toString(nums));
    8. }
    9. public static void quickSort(int []nums,int left , int right){
    10. if(left>=right){
    11. return;
    12. }
    13. int mid = partition(nums,left,right);
    14. quickSort(nums,left,mid-1);
    15. quickSort(nums,mid+1,right);
    16. }
    17. public static int partition(int []nums , int left , int right){
    18. int flag = left ;
    19. int index = left + 1;
    20. for (int i=index;i<=right;i++){
    21. if(nums[flag]>nums[i]){
    22. swap(nums,index,i);
    23. index ++;
    24. }
    25. }
    26. swap(nums,index - 1,flag);
    27. return index -1;
    28. }
    29. public static void swap(int[] nums, int i, int j) {
    30. int tep = nums[i];
    31. nums[i] = nums[j];
    32. nums[j] = tep;
    33. }
    34. }

    归并排序

    1. import java.util.Arrays;
    2. public class Main {
    3. static int i = 0;
    4. public static void main(String[] args) {
    5. int[] nums = new int[]{1, 3, 5, 7, 9, 0, 2, 4, 6, 8, 10};
    6. mergeSort(nums, 0, nums.length - 1);
    7. System.out.println(Arrays.toString(nums));
    8. }
    9. public static void mergeSort(int[] nums, int left, int right) {
    10. if (left >= right) return;
    11. int mid = left + (right - left) / 2;
    12. mergeSort(nums, left, mid);
    13. mergeSort(nums, mid + 1, right);
    14. sort(nums, left, mid, right);
    15. }
    16. private static void sort(int[] nums, int left, int mid, int right) {
    17. int i = left;
    18. int j = mid + 1;
    19. int index = 0;
    20. int[] tep = new int[right - left + 1];
    21. while (i <= mid && j <= right) {
    22. if (nums[i] > nums[j]) {
    23. tep[index++] = nums[j++];
    24. } else {
    25. tep[index++] = nums[i++];
    26. }
    27. }
    28. while (i <= mid) {
    29. tep[index++] = nums[i++];
    30. }
    31. while (j <= right) {
    32. tep[index++] = nums[j++];
    33. }
    34. index = 0;
    35. for (i = left; i <= right; i++) {
    36. nums[i] = tep[index++];
    37. }
    38. }
    39. public static void swap(int[] nums, int i, int j) {
    40. int tep = nums[i];
    41. nums[i] = nums[j];
    42. nums[j] = tep;
    43. }
    44. }

    leftBound

    1. import java.util.Arrays;
    2. public class Main {
    3. static int i = 0;
    4. public static void main(String[] args) {
    5. int[] nums = new int[]{1, 4, 5, 7, 9, 0, 2, 4, 6, 8, 10};
    6. Arrays.sort(nums);
    7. System.out.println(leftBound(nums, 4));
    8. }
    9. public static int leftBound(int[] nums, int key) {
    10. int left = 0;
    11. int right = nums.length - 1;
    12. while (left <= right) {
    13. int mid = left + (right - left) / 2;
    14. if (key == nums[mid]) {
    15. right = mid - 1;
    16. } else if (key > nums[mid]) {
    17. left = mid + 1;
    18. } else if (key < nums[mid]) {
    19. right = mid - 1;
    20. }
    21. }
    22. if (left >= nums.length || nums[left] != key) {
    23. return -1;
    24. }
    25. return left;
    26. }
    27. }

    rightBound

    1. import java.util.Arrays;
    2. public class Main {
    3. static int i = 0;
    4. public static void main(String[] args) {
    5. int[] nums = new int[]{1, 4, 5, 7, 9, 0, 2, 4, 6, 8, 10};
    6. Arrays.sort(nums);
    7. System.out.println(rightBound(nums, 4));
    8. }
    9. public static int rightBound(int[] nums, int key) {
    10. int left = 0;
    11. int right = nums.length - 1;
    12. while (left <= right) {
    13. int mid = left + (right - left) / 2;
    14. if (key == nums[mid]) {
    15. left = mid + 1;
    16. } else if (key > nums[mid]) {
    17. left = mid + 1;
    18. } else if (key < nums[mid]) {
    19. right = mid - 1;
    20. }
    21. }
    22. if (right <= 0 || nums[right] != key) {
    23. return -1;
    24. }
    25. return right;
    26. }
    27. }

    LRU

    1. import java.util.HashMap;
    2. class Node{
    3. String key;
    4. Object value;
    5. Node pre,next;
    6. }
    7. class LRU {
    8. HashMap map ;
    9. Node head,tail;
    10. int size;
    11. int max ;
    12. public LRU(int max){
    13. this.max = max;
    14. this.size = 0;
    15. map = new HashMap<>();
    16. head = new Node();
    17. tail = new Node();
    18. head.pre = null;
    19. tail.next =null;
    20. tail.pre = head;
    21. head.next = tail;
    22. }
    23. public void add(String key , Object value){
    24. if(map.containsKey(key)){
    25. Node tep = map.get(key);
    26. tep.value = value;
    27. Node cpre = tep.pre;
    28. Node cnext = tep.next;
    29. cpre.next = cnext;
    30. cnext.pre = cpre;
    31. Node index = head.next;
    32. tep.pre = head;
    33. tep.next = index;
    34. head.next = tep;
    35. index.pre = tep;
    36. }else {
    37. Node tep = new Node();
    38. tep.key = key;
    39. tep.value = value;
    40. map.put(key,tep);
    41. Node index = head.next;
    42. tep.pre = head;
    43. tep.next = index;
    44. head.next = tep;
    45. index.pre = tep;
    46. size ++;
    47. if (size > max){
    48. Node t = tail.pre.pre;
    49. String tt = tail.pre.key;
    50. t.next = tail;
    51. tail.pre = t;
    52. map.remove(tt);
    53. }
    54. }
    55. }
    56. public Object get(String key){
    57. if(!map.containsKey(key)){
    58. return null;
    59. }
    60. Node res = map.get(key);
    61. Node cpre = res.pre;
    62. Node cnext = res.next;
    63. cpre.next = cnext;
    64. cnext.pre = cpre;
    65. Node index = head.next;
    66. res.pre = head;
    67. res.next = index;
    68. head.next = res;
    69. index.pre = res;
    70. return res.value;
    71. }
    72. }
    73. class Main{
    74. public static void main(String[] args) {
    75. LRU lru = new LRU(3);
    76. lru.add("a","a");
    77. lru.add("c","c");
    78. lru.add("b","b");
    79. lru.get("a");
    80. lru.add("d","d");
    81. Node cv = lru.head.next;
    82. while (cv!=lru.tail){
    83. System.out.println(cv.key+" "+cv.value);
    84. cv = cv.next;
    85. }
    86. }
    87. }

  • 相关阅读:
    SpringBoot整合Redis_自定义RedisTemplate
    高压放大器在超声马达中的应用有哪些
    社区投稿| 以安全视角,深度剖析 Sui Staking 与 LSD
    后台开发核心技术与应用实践看书笔记(三):常用STL的使用
    2Gcsv文件打不开怎么处理,使用byzer工具
    Python + Django4 搭建个人博客(二):准备开发环境
    [附源码]计算机毕业设计JAVAssm实验教学资源管理系统
    weblogic/CVE-2018-2894文件上传漏洞复现
    7.nginx常用功能模块
    锐捷端口安全实验配置
  • 原文地址:https://blog.csdn.net/qq_41593124/article/details/126901223