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

public class Main {
    static  int i = 0;
    public static void main(String[] args) {
        Object o = new Object();

        new Thread(()->{

                while(i<100){
                    synchronized (o) {
                        if((i&1) ==0){
                            System.out.println(Thread.currentThread().getName()+":"+i);
                            o.notify();
                            i++;
                        }else {
                            try {
                                o.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

        },"偶数线程").start();
        new Thread(()->{

            while(i<100){
                synchronized (o) {
                    if((i&1) ==1){
                        System.out.println(Thread.currentThread().getName()+":"+i);
                        o.notify();
                        i++;
                    }else {
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        },"奇数线程").start();
    }
}

堆排序

import java.util.Arrays;

public class Main {
    static  int i = 0;
    public static void main(String[] args) {
       int []nums = new int[]{1,3,5,7,9,0,2,4,6,8,10};
       heapSort(nums);
        System.out.println(Arrays.toString(nums));
    }
    public static void heapSort(int []nums){
        int len = nums.length;
        initHeap(nums,len);
        int index = len - 1;
        for (int i =0;i<len;i++){
            swap(nums,0,index);
            heapfying(nums,0,index);
            index --;
        }
    }

    private static void initHeap(int[] nums, int len) {
        for (int i = len / 2  - 1 ;i>=0;i--){
            heapfying(nums,i,len);
        }
    }

    private static void heapfying(int[] nums, int i, int len) {
        int left = 2 * i + 1;
        int right = 2 *i + 2;
        int max_index  = i;
        if(left < len &&nums[left] > nums[max_index]){
            max_index = left;
        }
        if(right < len &&nums[right] > nums[max_index]){
            max_index = right;
        }
        if(i != max_index){
            swap(nums,i,max_index);
            heapfying(nums,max_index,len);
        }
    }

    private static void swap(int[] nums, int i, int j) {
        int tep = nums[i];
        nums[i] = nums[j];
        nums[j] = tep;
    }
}

快排序

import java.util.Arrays;

public class Main {
    static  int i = 0;
    public static void main(String[] args) {
       int []nums = new int[]{1,3,5,7,9,0,2,4,6,8,10};
        quickSort(nums,0,nums.length-1);
        System.out.println(Arrays.toString(nums));
    }
   public static void quickSort(int []nums,int left , int right){
        if(left>=right){
            return;
        }
       int mid = partition(nums,left,right);
       quickSort(nums,left,mid-1);
       quickSort(nums,mid+1,right);
   }
   public static int partition(int []nums , int left , int right){
        int flag = left ;
        int index = left + 1;
        for (int i=index;i<=right;i++){
            if(nums[flag]>nums[i]){
                swap(nums,index,i);
                index ++;
            }
        }
        swap(nums,index - 1,flag);
        return index -1;
   }
   public static void swap(int[] nums, int i, int j) {
        int tep = nums[i];
        nums[i] = nums[j];
        nums[j] = tep;
    }
}

归并排序

    import java.util.Arrays;
    
    public class Main {
        static int i = 0;
    
        public static void main(String[] args) {
            int[] nums = new int[]{1, 3, 5, 7, 9, 0, 2, 4, 6, 8, 10};
            mergeSort(nums, 0, nums.length - 1);
            System.out.println(Arrays.toString(nums));
        }
    
        public static void mergeSort(int[] nums, int left, int right) {
            if (left >= right) return;
            int mid = left + (right - left) / 2;
            mergeSort(nums, left, mid);
            mergeSort(nums, mid + 1, right);
            sort(nums, left, mid, right);
    
        }
    
        private static void sort(int[] nums, int left, int mid, int right) {
            int i = left;
            int j = mid + 1;
            int index = 0;
            int[] tep = new int[right - left + 1];
            while (i <= mid && j <= right) {
                if (nums[i] > nums[j]) {
                    tep[index++] = nums[j++];
                } else {
                    tep[index++] = nums[i++];
                }
            }
            while (i <= mid) {
                tep[index++] = nums[i++];
            }
            while (j <= right) {
                tep[index++] = nums[j++];
            }
            index = 0;
            for (i = left; i <= right; i++) {
                nums[i] = tep[index++];
            }
        }
    
        public static void swap(int[] nums, int i, int j) {
            int tep = nums[i];
            nums[i] = nums[j];
            nums[j] = tep;
        }
    }

leftBound

import java.util.Arrays;

public class Main {
    static int i = 0;

    public static void main(String[] args) {
        int[] nums = new int[]{1, 4, 5, 7, 9, 0, 2, 4, 6, 8, 10};
        Arrays.sort(nums);
        System.out.println(leftBound(nums, 4));
    }

    public static int leftBound(int[] nums, int key) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (key == nums[mid]) {
                right = mid - 1;
            } else if (key > nums[mid]) {
                left = mid + 1;
            } else if (key < nums[mid]) {
                right = mid - 1;
            }
        }
        if (left >= nums.length || nums[left] != key) {
            return -1;
        }
        return left;
    }
}

rightBound

import java.util.Arrays;

public class Main {
    static int i = 0;

    public static void main(String[] args) {
        int[] nums = new int[]{1, 4, 5, 7, 9, 0, 2, 4, 6, 8, 10};
        Arrays.sort(nums);
        System.out.println(rightBound(nums, 4));
    }

    public static int rightBound(int[] nums, int key) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (key == nums[mid]) {
                left = mid + 1;
            } else if (key > nums[mid]) {
                left = mid + 1;
            } else if (key < nums[mid]) {
                right = mid - 1;
            }
        }
        if (right <= 0 || nums[right] != key) {
            return -1;
        }
        return right;
    }
}

LRU

import java.util.HashMap;

class Node{
    String key;
    Object value;
    Node pre,next;
}

class LRU {
   HashMap<String,Node> map ;
   Node head,tail;
   int size;
   int max ;
   public LRU(int max){
       this.max = max;
       this.size = 0;
       map = new HashMap<>();
       head = new Node();
       tail = new Node();
       head.pre = null;
       tail.next =null;
       tail.pre = head;
       head.next = tail;
   }
   public void add(String key , Object value){
       if(map.containsKey(key)){
            Node tep = map.get(key);
            tep.value = value;

            Node cpre = tep.pre;
            Node cnext = tep.next;
            cpre.next = cnext;
            cnext.pre = cpre;

            Node index = head.next;
            tep.pre = head;
            tep.next = index;
            head.next = tep;
            index.pre = tep;

       }else {
           Node tep = new Node();
           tep.key = key;
           tep.value = value;
           map.put(key,tep);

           Node index = head.next;
           tep.pre = head;
           tep.next = index;
           head.next = tep;
           index.pre = tep;

           size ++;
           if (size > max){
               Node t = tail.pre.pre;
               String tt = tail.pre.key;
               t.next = tail;
               tail.pre = t;
               map.remove(tt);
           }
       }
   }
   public Object get(String key){
        if(!map.containsKey(key)){
            return null;
        }
        Node res = map.get(key);

       Node cpre = res.pre;
       Node cnext = res.next;
       cpre.next = cnext;
       cnext.pre = cpre;

       Node index = head.next;
       res.pre = head;
       res.next = index;
       head.next = res;
       index.pre = res;

       return res.value;
   }
}

class Main{
    public static void main(String[] args) {
        LRU lru = new LRU(3);
        lru.add("a","a");
        lru.add("c","c");
        lru.add("b","b");
        lru.get("a");
        lru.add("d","d");
        Node cv = lru.head.next;
        while (cv!=lru.tail){
            System.out.println(cv.key+" "+cv.value);
            cv = cv.next;
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿联爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值