排序问题—java实现

 冒泡排序

算法思想:

每次比较相邻元素,若逆序则交换位置,每一趟比较n-1次,确定一个最大值。故需比较n趟,来确定n个数的位置。

  • 外循环来表示比较的趟数,每一趟确定一个最大数的位置
  • 内循环来表示相邻数字两两比较。

 private static void bubble_sort(int[] nums) {
        for (int i = 0; i < nums.length; i++){
            for (int j = 0; j < nums.length-1; j++){
                if (nums[j]>nums[j+1]) {
                    int temp=nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
            }
        }
    }

改进:

记录某次遍历时最后发生数据交换的位置pos,这个位置之后的数据显然已经有序了。因此通过记录最后发生数据交换的位置就可以确定下次循环的范围了。由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。

private static void bubble_sort2(int[] nums) {
        for (int i = 0; i < nums.length; i++){
            int flag=nums.length-1;
            for (int j = 0; j < flag; j++){//扫描的位置
                if (nums[j]>nums[j+1]) {
                    int temp=nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                    flag=j;//交换的位置
                }
            }
        }
    }
  • 平均时间复杂度:O(N^2)
  • 最佳时间复杂度:O(N)
  • 最差时间复杂度:O(N^2)
  • 空间复杂度:O(1)

插入排序

插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间(去存待插入的元素)的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

① 从第一个元素开始,该元素可以认为已经被排序
② 取出下一个元素,在已经排序的元素序列中从后向前扫描
③如果该元素(已排序)大于待插入元素,将该元素移到下一位置
④ 重复步骤③,直到找到已排序的元素小于或者等于新元素的位置
⑤将新元素插入到该位置后
⑥ 重复步骤②~⑤

private static void InsertSort(int[] nums) {
        for (int i = 1; i <nums.length; i++) {//从第二个元素开始插入
            int temp = nums[i];
            int j;
            for (j=i-1; j >= 0; j--) {//已排好序的是待插入元素之前的,从后往前依次比较
                if (temp<nums[j]) nums[j+1]=nums[j];//往后移一位
                else break;//找到比待插入元素小的,此时将待插入元素插入此元素的后面
            }
            nums[j+1]=temp;//将待插入元素插入此元素的后面
        }
    }

改进思路: 在往前找合适的插入位置时采用二分查找的方式,即折半插入。

private static void InsertSort2(int[] nums) {
        for (int i = 1; i <nums.length; i++) {//从第二个元素开始插入
            int temp = nums[i];
            int left = 0;
             int right = i-1;
            while (left<=right)//找比待插入元素小的元素的位置left
            {
                int middle = (left+right)/2;
                if (nums[middle]>temp)
                    right = middle-1;
                else
                    left = middle+1;
            }
            int j;
            for (j=i-1; j >= left; j--) {//已排好序的是待插入元素之前的,从后往前依次比较
                 nums[j+1]=nums[j];//往后移一位

            }
            nums[j+1]=temp;//将待插入元素插入此元素的后面
        }
    }
  • 平均时间复杂度:O(N^2)
  • 最差时间复杂度:O(N^2)
  • 空间复杂度:O(1)
  • 排序方式:In-place
  • 稳定性:稳定

希尔排序

先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。

对相隔某个增量所构成的数组进行插入排序。

第一趟排序: 设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。接下来,按照直接插入排序的方法对每个组进行排序。
第二趟排序
将上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为2组。按照直接插入排序的方法对每个组进行排序。
第三趟排序
再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为1的元素组成一组,即只有一组。按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。

    private static void Shellsort(int[] nums) {
        for (int gap=nums.length/2; gap>0; gap/=2) {//定义间隔
            //插入排序
            for (int i=gap;i<nums.length;i++) {
                int temp=nums[i];
                int j;
                for (j=i-gap;j>=0;j-=gap) {
                    if (temp<nums[j]) nums[j+gap]=nums[j];
                    else break;
                }
                nums[j+gap]=temp;
            }
        }
    }
  • 平均时间复杂度:O(Nlog2N)
  • 最佳时间复杂度:
  • 最差时间复杂度:O(N^2)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 复杂性:较复杂

选择排序

首先在序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

特别注意:这里需要将已找到的最小值与已排好序的最后一个进行比较,因此再求最小值时,求最小值的坐标 

int min=j;//min用来记录最小值的坐标
for (; j < nums.length; j++) {
    if (nums[j] < nums[min]) min=j;
}
    private static void selectSort(int[] nums) {
        for (int i = 1; i < nums.length; i++) {
            int j=i;
            int min=j;//min用来记录最小值的坐标
            for (; j < nums.length; j++) {
                if (nums[j] < nums[min]) min=j;
            }
            if(nums[min]<nums[i-1]){
                int temp=nums[i-1];
                nums[i-1]=nums[min];
                nums[min]=temp;
            }
        }
    }
  • 平均时间复杂度:O(N^2)
  • 最佳时间复杂度:O(N^2)
  • 最差时间复杂度:O(N^2)
  • 空间复杂度:O(1)
  • 排序方式:In-place
  • 稳定性:不稳定

改进方法:上述方法每次只确定一个最小值,可采取每一次比较找出最大值与最小值,同时确定两个值。

快速排序

通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

快速排序使用分治法策略来把一个序列分为两个子序列。

① 从数列中挑出一个元素,称为 “基准值”(以第一个为例)
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区操作。

在数组的头部和尾部分别设置一个哨兵,同时向对方走去。尾部的哨兵如发现有比基准数小的数,停下。头部的哨兵如发现有比基准数大的数,停下。交换两个数。再重新走重复前面的交换过程。直到两个哨兵相遇,交换基准数和尾哨兵
③ 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

特别注意:若以第一个元素为基准数,在哨兵互走过程需右边的哨兵先走。 原因很好理解,哨兵互走交换的过程就是不断排序的过程。若右边的哨兵先走,不管走多少次,最后相遇时的那个数是小于基准数的。这时与基准数交换,正好分为两个序列。可若是左边的先走,相遇在大于基准数上就不好办了。

private static void quickSort(int[] nums,int start,int end) {
        if (start>=end) return;
        int pivot = nums[start];
        int i=start;
        int j=end;
        while(i < j){
            while (nums[j]>pivot&&i<j) j--;//右哨兵先走
            while (nums[i]<=pivot&&i<j) i++;
            //以上两个循环找到左侧比pivot大的与右侧比pivot小的
            swap(nums,i,j);
        }//此循环将比pivot大的分一组,小的分一组
        //最终位置,最后一个小于pivot的位置是j指向的
        swap(nums,start,j);//将基准值插入中间,即此时j指向pivot的位置
        quickSort(nums,start,j-1);
        quickSort(nums,j+1,end);

    }
  • 平均时间复杂度:O(NlogN)
  • 最佳时间复杂度:O(NlogN)
  • 最差时间复杂度:O(N^2)
  • 空间复杂度:根据实现方式的不同而不同

快速排序的三指针思想 

scan指针:从头到尾扫描元素

equal指针:存与基准值相等的区间的起始位置

big指针:存比基准值大的区间的起始位置

    private static void quick_sort3(int []nums,int start,int end){
        int scan = start+1;
        int equal = scan;
        int big = end;
        //设置退出条件
        if(scan >= big) return ;
        //选择主元,一般为首元
        int num = nums[start];
        /*
         * 当smaller扫描到的数字小于主元,则下标为smaller和equal的需要交换数据,这样就又将小于主元的放在一起了,然后smaller和equal都要自增
         * 当smaller扫描到的数字等于主元,直接将smaller自增
         * 当smaller扫描到的数字大于主元,就将小标为smaller和bigger上的数据交换,bigger再自减(和单向扫描分区法处理一样)
         */
        while(scan < big) {
            //注意以下三种情况(互斥)每扫一次,只执行一个if语句(不能三个都执行),故不能少写else
            if(nums[scan] < num) {
                swap(nums, equal, scan);
                equal++;
                scan++;
            }
            else if(nums[scan] == num) {
                scan++;
            }
            else if(nums[scan] > num) {
                swap(nums, scan, big);
                big--;
            }
        }
        //交换首元与right上的数
        swap(nums,start,equal-1);
        //继续将right两边的数组进行快速排
        quick_sort3(nums,start,equal-2);
        quick_sort3(nums,big+1,end);
    }

归并排序

首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的有序的数据,再把这些有序的数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。

    private static int[] Mergesort(int[] nums) {
        if (nums.length<=1) return nums;
        int mid= (nums.length-1)/2;
        //int []left=Arrays.copyOfRange(nums,0,mid+1);
        //int []right=Arrays.copyOfRange(nums,mid+1,nums.length);
        int []sortleft =Mergesort(Arrays.copyOfRange(nums,0,mid+1));
        int []sortright=Mergesort(Arrays.copyOfRange(nums,mid+1,nums.length));
        return merge(sortleft,sortright,nums);

    }

    private static int[] merge(int[] sortleft, int[] sortright, int[] nums) {
        int l=0;
        int r=0;
        int index=0;
        while (l<sortleft.length && r<sortright.length){
            if (sortleft[l]<sortright[r]){
                nums[index]=sortleft[l];
                l++;
                index++;
            }else {
                nums[index]=sortright[r];
                r++;
                index++;
            }
        }
        while (l<sortleft.length) nums[index++]=sortleft[l++];
        while (r<sortright.length) nums[index++]=sortright[r++];
        return nums;
    }
    private static int[] mergerSort(int[] nums) {//形成有序数列
        if (nums.length <= 1) return nums;
        int mid= (nums.length-1)/2;
        //划分为两部分
        int []left = Arrays.copyOfRange(nums,0,mid+1);
        int []right = Arrays.copyOfRange(nums,mid+1,nums.length);
        //将左右变为有序数列
        int []sortleft = mergerSort(left);
        int []sortright = mergerSort(right);
        //归并
        int m = 0, i = 0, j = 0;
        while (i < sortleft.length && j < sortright.length) {
            nums[m++] = sortleft[i] < sortright[j] ? sortleft[i++] : sortright[j++];
        }
        while (i < sortleft.length)
            nums[m++] = sortleft[i++];
        while (j < sortright.length)
            nums[m++] = sortright[j++];
        return nums;

    }
  • 平均时间复杂度:O(nlogn)
  • 最佳时间复杂度:O(n)
  • 最差时间复杂度:O(nlogn)
  • 空间复杂度:O(n)
  • 排序方式:In-place
  • 稳定性:稳定

计数排序

计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。

① 找出待排序的数组中最大和最小的元素
② 统计数组中每个值为i的元素出现的次数,存入数组C的第i项
③ 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
④ 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

    private static int[] countSort(int[] nums) {
        int min = nums[0];
        int max = nums[0];
        for (int i = 1; i< nums.length;i++){
            if (nums[i] < min) min = nums[i];
            if (nums[i] > max) max = nums[i];
        }
        int [] count = new int[max-min+1];
        for (int i=0;i<nums.length;i++){
            count[nums[i]-min]++;//count[i]表示nums中i出现的次数。
        }
        int []newnum =new int[nums.length];
        int j=0;
        for (int i=0;i<count.length;i++){
            while (count[i]>0){
                newnum[j++] = i+min;
                count[i]--;
            }
        }
        return newnum;
    }

桶排序

桶排序假设待排序的一组数均匀独立的分布在一个范围中,并将这一范围划分成几个子范围(每个桶的范围成顺序)。然后基于某种映射函数f ,将待排序列的元素映射到第i个桶中。

映射函数一般是 f = array[i] / k; k^2 = n; n是所有元素个数

    private static void bucketSort(int[] nums) {
        int n = nums.length;
        if (n <= 0)
            return;
        ArrayList<Integer>[] bucket = new ArrayList[n];
        // 创建空桶
        for (int i = 0; i < n; i++)
            bucket[i] = new ArrayList<Integer>();
        // 根据规则将序列中元素分散到桶中,每个桶之间的大小区间有顺序
        for (int i = 0; i < n; i++) {
            int bucketIndex = (int) (nums[i] / Math.sqrt(n));//映射函数
            bucket[bucketIndex].add(nums[i]);
        }
        // 对各个桶内的元素进行排序
        for (int i = 0; i < n; i++) {
            Collections.sort((bucket[i]));
        }
        // 合并所有桶内的元素
        int index = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0, size = bucket[i].size(); j < size; j++) {
                nums[index++] = bucket[i].get(j);
            }
        }
    }
  • 平均时间复杂度:O(n + k)
  • 最佳时间复杂度:O(n + k)
  • 最差时间复杂度:O(n ^ 2)
  • 空间复杂度:O(n * k)
  • 稳定性:稳定

基数排序

原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。

① 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。
② 从最低位开始,依次进行一次排序。
③ 这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

    private static void RadixSort(int[] nums) {
        int maxlen=maxIndex(nums);
        int radix=1;
        for (int i=0; i<maxlen; i++){//位数等于排序次数
            //桶排序
            ArrayList<Integer> []lists= new ArrayList[10];
            for (int j=0; j< 10; j++) lists[j]=new ArrayList<>();
            for (int j=0;j< nums.length;j++){
                lists[(nums[j]/radix)%10].add(nums[j]);
            }
            for (int j=0;j<10;j++) Collections.sort(lists[j]);
            int index = 0;
            for (int k = 0; k < nums.length; k++) {
                for (int j = 0, size = lists[k].size(); j < size; j++) {
                    nums[index++] = lists[k].get(j);
                }
            }
            //依次取个位、十位、、、、
            radix*=10;
        }
    }
  • 时间复杂度:O(k*N)
  • 空间复杂度:O(k + N)
  • 稳定性:稳定 

堆排序

堆是一种特殊的树。只要满足以下两点,它就是一个堆:

  • 堆是一个完全二叉树;
  • 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。

堆的构造

一般用数组(层序排列)来表示堆,用数组的1号下标存储根节点。那么对于一般的节点 i,其左孩子为 i*2,右孩子为 i*2+1,其父亲节点则为 i/2。(当然所有派生出来的节点x都要先判断 0<x<=n,表示存在

①首先我们将数组我们将数组从上至下按顺序排列,转换成二叉树:一个无序堆。每一个三角关系都是一个堆,上面是父节点,下面两个分叉是子节点,两个子节点俗称左孩子、右孩子;

②转换成无序堆之后,我们要努力让这个无序堆变成最大堆(或是最小堆),即每个堆里都实现父节点的值都大于任何一个子节点的值。

③从最后一个堆开始,即左下角那个没有右孩子的那个堆开始;首先对比左右孩子,由于这个堆没有右孩子,所以只能用左孩子,左孩子的值比父节点的值小所以不需要交换。如果发生交换,要检测子节点是否为其他堆的父节点,如果是,递归进行同样的操作。

④第二次对比红色三角形内的堆,取较大的子节点,右孩子8胜出,和父节点比较,右孩子8大于父节点3,升级做父节点,与3交换位置,3的位置没有子节点,这个堆建成最大堆。

⑤对黄色三角形内堆进行排序,过程和上面一样,最终是右孩子33升为父节点,被交换的右孩子下面也没有子节点,所以直接结束对比。

⑥最顶部绿色的堆,堆顶100比左右孩子都大,所以不用交换,至此最大堆创建完成。

堆的插入(以大根堆为例)

插入元素的位置,一定是n的下一个位置。

再将形成的堆进行堆化调整(自底向上),是每个节点均符合大根堆的性质。

删除堆顶元素

用最后一个结点覆盖堆顶节点,然后堆调整。

堆排序

基本思想:不断取出堆顶元素,进行堆调整

①首先将堆顶元素100交换至最底部7的位置,7升至堆顶,100所在的底部位置即为有序区,有序区不参与之后的任何对比。

②在7升至顶部之后,对顶部重新做最大堆调整,左孩子33代替7的位置。

③在7被交换下来后,下面还有子节点,所以需要继续与子节点对比,左孩子11比7大,所以11与7交换位置,交换位置后7下面为有序区,不参与对比,所以本轮结束,无序区再次形成一个最大堆。

④将最大堆堆顶33交换至堆末尾,扩大有序区;

⑤不断建立最大堆,并且扩大有序区,最终全部有序。

public void sort(){
        /*
         *  第一步:将数组堆化
         *  beginIndex = 第一个非叶子节点。
         *  从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
         *  叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大。
         */
        int len = arr.length - 1;
        int beginIndex = (len - 1) >> 1;
        for(int i = beginIndex; i >= 0; i--){
            maxHeapify(i, len);
        }

        /*
         * 第二步:对堆化数据排序
         * 每次都是移出最顶层的根节点A[0],与最尾部节点位置调换,同时遍历长度 - 1。
         * 然后从新整理被换到根节点的末尾元素,使其符合堆的特性。
         * 直至未排序的堆长度为 0。
         */
        for(int i = len; i > 0; i--){
            swap(0, i);
            maxHeapify(0, i - 1);
        }
    }

private void maxHeapify(int index,int len){
        int li = (index << 1) + 1; // 左子节点索引
        int ri = li + 1;           // 右子节点索引
        int cMax = li;             // 子节点值最大索引,默认左子节点。

        if(li > len) return;       // 左子节点索引超出计算范围,直接返回。
        if(ri <= len && arr[ri] > arr[li]) // 先判断左右子节点,哪个较大。
            cMax = ri;
        if(arr[cMax] > arr[index]){
            swap(cMax, index);      // 如果父节点被子节点调换,
            maxHeapify(cMax, len);  // 则需要继续判断换下后的父节点是否符合堆的特性。
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/467910.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在wps的excel表格里面使用动态gif图

1、新建excel表格&#xff0c;粘贴gif图到表格里面&#xff0c;鼠标右键选择超链接。 找到源文件&#xff0c; 鼠标放到图片上的时候&#xff0c;待有个小手图标&#xff0c;双击鼠标可以放大看到动态gif图。 这种方式需要确保链接的原始文件位置和名称不能变化&#xff01;&a…

阿里云发布 AI 编程助手 “通义灵码”——VSCode更强了 !!

文章目录 什么是 通义灵码&#xff08;TONGYI Lingma&#xff09; 快速体验“通义灵码” 什么是“通义灵码”&#xff08;TONGYI Lingma&#xff09; 通义灵码&#xff08;TONGYI Lingma&#xff09;&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff…

创建一个electron-vite项目

前置条件&#xff1a;非常重要&#xff01;&#xff01;&#xff01; npm: npm create quick-start/electronlatest yarn: yarn create quick-start/electron 然后进入目录&#xff0c;下载包文件&#xff0c;运行项目 到以上步骤&#xff0c;你已经成功运行起来一个 electr…

从底层结构开始学习FPGA(0)----FPGA的硬件架构层次(BEL Site Tile FSR SLR Device)

系列目录与传送门 《从底层结构开始学习FPGA》目录与传送门 Xilinx的FPGA&#xff0c;从硬件架构的角度可以划分为6个层次&#xff0c;从底层到顶层依次是&#xff1a; BEL&#xff08;最底层单元&#xff09;SiteTileFSRSLRDevice&#xff08;FPGA芯片&#xff09; 接下来我…

论文解析:V3D: Video Diffusion Models are Effective 3DGenerators

摘要&#xff1a; 自动三维生成最近引起了广泛关注。最近的方法大大加快了生成速度&#xff0c;但由于模型容量有限或三维数据&#xff0c;生成的物体通常不够精细。在视频扩散模型最新进展的推动下&#xff0c;我们引入了 V3D&#xff0c;利用预训练视频扩散模型的世界模拟能…

力扣17. 电话号码的字母组合

Problem: 17. 电话号码的字母组合 文章目录 思路及解法复杂度Code 题目描述 思路及解法 1.将电话号码和对应的数组存入数组中创建映射关系&#xff1b; 2.编写&#xff0c;并调用回溯函数&#xff0c;当决策阶段等于digits的长度时&#xff0c;将当前的决策路径添加到结果集合中…

自学Python第二十九天-feapder框架创建爬虫

自学Python第二十九天-feapder框架创建爬虫 安装feapder 的设计架构feapder 框架的简单使用简单创建爬虫简单爬取数据简单的数据保存 中间件校验浏览器渲染使用浏览器渲染获取接口数据 feapder是一款上手简单&#xff0c;功能强大的 Python爬虫框架&#xff0c;内置 AirSpide…

linux安装WordPress问题汇总,老是提示无法连接到FTP服务器解决方案

最近在做一些建站相关的事情&#xff0c;遇到一些大大小小的问题都整理在这里 1.数据库密码和端口&#xff0c;千万要复杂一点&#xff0c;不要使用默认的3306端口 2.wordpress算是一个php应用吧&#xff0c;所以安装流程一般是 apache http/nginx——php——mysql——ftp &…

嵌入式学习第二十九天!(数据结构的概念、单向链表)

数据结构&#xff1a; 1. 定义&#xff1a; 一组用来保存一种或者多种特定关系的数据的集合&#xff08;组织和存储数据&#xff09; 1. 程序设计&#xff1a; 将现实中大量而复杂的问题以特定的数据类型和特定的数据结构存储在内存中&#xff0c;并在此基础上实现某个特定的功…

Python深度学习技术教程

原文链接&#xff1a;Python深度学习技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597949&idx4&sn65c0d353d02b060fec98ec799f217ae1&chksmfa823e9acdf5b78cd71cfcb060e3b60125b17afbe3e19ef423d4709d2df7fc93d90ce3097253&token14787…

【K8S】docker和K8S(kubernetes)理解?docker是什么?K8S架构、Master节点 Node节点 K8S架构图

docker和K8S理解 一、docker的问世虚拟机是什么&#xff1f;Docker的问世&#xff1f;docker优点及理解 二、Kubernetes-K8SK8S是什么&#xff1f;简单了解K8S架构Master节点Node节点K8S架构图 一、docker的问世 在LXC(Linux container)Linux容器虚拟技术出现之前&#xff0c;业…

汽车功能安全整体方法

摘 要 ISO26262道路车辆功能安全标准已经制定实践了多年&#xff0c;主要目标是应对车辆的电子和电气&#xff08;E/E&#xff09;系统失效。该方法践行至今&#xff0c;有些系统功能安全方法已经成熟&#xff0c;例如电池管理系统&#xff08;BMS&#xff09;&#xff0c;并且…

Javaweb学习记录(三)请求响应案例

下面为一个请求响应案例&#xff0c;postman发送请求&#xff0c;服务器响应将一个xml文件中的数据通过读取解析&#xff0c;将其用Result类标准的格式返回前端&#xff0c;在前端用json的方式显示 后端Controller代码 1、通过本类的字节码文件得到类加载器并寻找到需要解析的…

vue2使用webSocket双向通讯

基于webSocket实现双向通信&#xff0c;使用webworker保持心跳。 由于浏览器的资源管理策略会暂停或限制某些资源的消耗&#xff0c;导致前端心跳包任务时效&#xff0c;后端接收不到webSocket心跳主动断开&#xff0c;因此需要使用webworker保持心跳 引入webworker npm insta…

【Ubuntu】Ubuntu的安装和配置

下载ubuntu镜像 https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-desktop-amd64.iso 一、Ubuntu安装 1.新建虚拟机 1.1按照它的提示创建用户&#xff1b;后面一直下一步就好 2.启动Ubuntu虚拟机 2.1设置为中文键盘 2.2默认即可&#xff1b;若是有低需求也可以选择最小…

Coursera上Golang专项课程3:Concurrency in Go 学习笔记(完结)

Concurrency in Go 本文是 Concurrency in Go 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Concurrency in GoMODULE 1: Why Use Concurrency?Learning Objectives M1.1.1 - Parallel ExecutionM1.1.2 - Von Neumann BottleneckM1.1.3 - Power W…

Python基础(六)之数值类型元组

Python基础&#xff08;六&#xff09;之数值类型元组 1、简介 元组&#xff1a; 在Python中是内置的数据结构之一&#xff0c;是一个不可变的序列,切可以是任何类型数据。元组的元素放在&#xff08;&#xff09;小括号内。一般我们希望数据不改变的时候使用 不可变与可变的…

Day69:WEB攻防-Java安全JWT攻防Swagger自动化算法签名密匙Druid泄漏

目录 Java安全-Druid监控-未授权访问&信息泄漏 黑盒发现 白盒发现 攻击点 Java安全-Swagger接口-导入&联动批量测试 黑盒发现 白盒发现 自动化发包测试 自动化漏洞测试 Java安全-JWT令牌-空算法&未签名&密匙提取 识别 JWT 方式一&#xff1a;人工识…

web渗透测试漏洞复现:Elasticsearch未授权漏洞复现

web渗透测试漏洞复现 Elasticsearch未授权漏洞复现Elasticsearch简介Elasticsearch复现Elasticsearch漏洞修复和加固措施 Elasticsearch未授权漏洞复现 Elasticsearch简介 Elasticsearch 是一款 Java 编写的企业级搜索服务&#xff0c;它以分布式多用户能力和全文搜索引擎为特…

使用jenkins-pipeline进行利用项目文件自动化部署到k8s上

Discard old builds:丢弃旧的构建,目的是管理存储空间、提升性能以及保持环境整洁 Do not allow concurrent builds: 禁止并发构建是指同一时间内只允许一个构建任务执行,避免多个构建同时运行可能带来的问题 Do not allow the pipeline to resume if the controller resta…