10大面试必备的排序算法 Python 实现(附源码)

news2024/11/21 2:33:47

今天给大家分享一篇关于Python实现排序算法的文章,来自GitHub。

排序算法是《数据结构与算法》中最基本的算法之一。

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:

文章目录

    • 技术交流
    • 关于时间复杂度
    • 关于稳定性
    • 名词解释
    • 1、冒泡排序
      • (1)算法步骤
      • (2)动图演示
      • (3)Python 代码
    • 2、选择排序
      • (1)算法步骤
      • (2)动图演示
      • (3)Python 代码
    • 3、插入排序
      • (1)算法步骤
      • (2)动图演示
      • (3)Python 代码
    • 4、希尔排序
      • (1)算法步骤
      • (2)Python 代码
    • 5、归并排序
      • (1)算法步骤
      • 2)动图演示
      • (3)Python 代码
    • 6、快速排序
      • (1)算法步骤
      • (2)动图演示
      • (3)Python 代码
    • 7、堆排序
      • (1)算法步骤
      • (2)动图演示
      • (3)Python 代码
    • 8、计数排序
      • (1)动图演示
      • (2)Python 代码
    • 9、桶排序
      • 什么时候最快
      • 什么时候最慢
      • Python 代码
    • 10、基数排序
      • 基数排序 vs 计数排序 vs 桶排序
      • 动图演示
      • Python 代码

技术交流

技术要学会分享、交流,不建议闭门造车。 本文由粉丝群小伙伴分享汇总。

论文探讨、算法实战交流、求职内推、干货分享、解惑答疑,与2000+来自港大、北大、腾讯、科大讯飞、阿里等开发者互动学习。

目前已开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式1、微信搜索公众号:机器学习社区,后台回复:加群;
方式2、可以直接加微信号:mlc2060。加的时候备注一下:研究方向
+学校/公司+CSDN,即可。然后就可以拉你进群了。

关于时间复杂度

  1. 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。

  2. 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;

  3. O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。希尔排序

  4. 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。

关于稳定性

  • 排序后 2 个相等键值的顺序和排序之前它们的顺序相同

  • 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。

  • 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。

名词解释

  • n:数据规模

  • k:“桶”的个数

  • In-place:占用常数内存,不占用额外内存

  • Out-place:占用额外内存

1、冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来说并没有什么太大作用。

(1)算法步骤

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

(2)动图演示

(3)Python 代码

def bubbleSort(arr):  
    for i in range(1, len(arr)):  
        for j in range(0, len(arr)-i):  
            if arr[j] > arr[j+1]:  
                arr[j], arr[j + 1] = arr[j + 1], arr[j]  
    return arr  

2、选择排序

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。

(1)算法步骤

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

  3. 重复第二步,直到所有元素均排序完毕。

(2)动图演示

(3)Python 代码

def selectionSort(arr):  
    for i in range(len(arr) - 1):  
        # 记录最小数的索引  
        minIndex = i  
        for j in range(i + 1, len(arr)):  
            if arr[j] < arr[minIndex]:  
                minIndex = j  
        # i 不是最小数时,将 i 和最小数进行交换  
        if i != minIndex:  
            arr[i], arr[minIndex] = arr[minIndex], arr[i]  
    return arr  

3、插入排序

插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。

(1)算法步骤

  1. 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

  2. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

(2)动图演示

(3)Python 代码

def insertionSort(arr):  
    for i in range(len(arr)):  
        preIndex = i-1  
        current = arr[i]  
        while preIndex >= 0 and arr[preIndex] > current:  
            arr[preIndex+1] = arr[preIndex]  
            preIndex-=1  
        arr[preIndex+1] = current  
    return arr  

4、希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;

  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

(1)算法步骤

  1. 选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

  2. 按增量序列个数 k,对序列进行 k 趟排序;

  3. 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

(2)Python 代码

def shellSort(arr):  
    import math  
    gap=1  
    while(gap < len(arr)/3):  
        gap = gap*3+1  
    while gap > 0:  
        for i in range(gap,len(arr)):  
            temp = arr[i]  
            j = i-gap  
            while j >=0 and arr[j] > temp:  
                arr[j+gap]=arr[j]  
                j-=gap  
            arr[j+gap] = temp  
        gap = math.floor(gap/3)  
    return arr  

5、归并排序

归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);

  • 自下而上的迭代;

和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。

(1)算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;

  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

  4. 重复步骤 3 直到某一指针达到序列尾;

  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

2)动图演示

(3)Python 代码

def mergeSort(arr):  
    import math  
    if(len(arr)<2):  
        return arr  
    middle = math.floor(len(arr)/2)  
    left, right = arr[0:middle], arr[middle:]  
    return merge(mergeSort(left), mergeSort(right))  
  
def merge(left,right):  
    result = []  
    while left and right:  
        if left[0] <= right[0]:  
            result.append(left.pop(0));  
        else:  
            result.append(right.pop(0));  
    while left:  
        result.append(left.pop(0));  
    while right:  
        result.append(right.pop(0));  
    return result  

6、快速排序

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。

快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。

快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:

快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

(1)算法步骤

① 从数列中挑出一个元素,称为 “基准”(pivot);

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

③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

(2)动图演示

(3)Python 代码

def quickSort(arr, left=None, right=None):  
    left = 0 if not isinstance(left,(int, float)) else left  
    right = len(arr)-1 if not isinstance(right,(int, float)) else right  
    if left < right:  
        partitionIndex = partition(arr, left, right)  
        quickSort(arr, left, partitionIndex-1)  
        quickSort(arr, partitionIndex+1, right)  
    return arr  
  
def partition(arr, left, right):  
    pivot = left  
    index = pivot+1  
    i = index  
    while  i <= right:  
        if arr[i] < arr[pivot]:  
            swap(arr, i, index)  
            index+=1  
        i+=1  
    swap(arr,pivot,index-1)  
    return index-1  
  
def swap(arr, i, j):  
    arr[i], arr[j] = arr[j], arr[i]  

7、堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;

  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

堆排序的平均时间复杂度为 Ο(nlogn)。

(1)算法步骤

  1. 创建一个堆 H[0……n-1];

  2. 把堆首(最大值)和堆尾互换;

  3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;

  4. 重复步骤 2,直到堆的尺寸为 1。

(2)动图演示

(3)Python 代码

def buildMaxHeap(arr):  
    import math  
    for i in range(math.floor(len(arr)/2),-1,-1):  
        heapify(arr,i)  
  
def heapify(arr, i):  
    left = 2*i+1  
    right = 2*i+2  
    largest = i  
    if left < arrLen and arr[left] > arr[largest]:  
        largest = left  
    if right < arrLen and arr[right] > arr[largest]:  
        largest = right  
  
    if largest != i:  
        swap(arr, i, largest)  
        heapify(arr, largest)  
  
def swap(arr, i, j):  
    arr[i], arr[j] = arr[j], arr[i]  
  
def heapSort(arr):  
    global arrLen  
    arrLen = len(arr)  
    buildMaxHeap(arr)  
    for i in range(len(arr)-1,0,-1):  
        swap(arr,0,i)  
        arrLen -=1  
        heapify(arr, 0)  
    return arr  

8、计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

(1)动图演示

(2)Python 代码

def countingSort(arr, maxValue):  
    bucketLen = maxValue+1  
    bucket = [0]*bucketLen  
    sortedIndex =0  
    arrLen = len(arr)  
    for i in range(arrLen):  
        if not bucket[arr[i]]:  
            bucket[arr[i]]=0  
        bucket[arr[i]]+=1  
    for j in range(bucketLen):  
        while bucket[j]>0:  
            arr[sortedIndex] = j  
            sortedIndex+=1  
            bucket[j]-=1  
    return arr  

9、桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量

  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

什么时候最快

当输入的数据可以均匀的分配到每一个桶中。

什么时候最慢

当输入的数据被分配到了同一个桶中。

Python 代码

def bucket_sort(s):  
    """桶排序"""  
    min_num = min(s)  
    max_num = max(s)  
    # 桶的大小  
    bucket_range = (max_num-min_num) / len(s)  
    # 桶数组  
    count_list = [ [] for i in range(len(s) + 1)]  
    # 向桶数组填数  
    for i in s:  
        count_list[int((i-min_num)//bucket_range)].append(i)  
    s.clear()  
    # 回填,这里桶内部排序直接调用了sorted  
    for i in count_list:  
        for j in sorted(i):  
            s.append(j)  
  
if __name__ == __main__ :  
    a = [3.2,6,8,4,2,6,7,3]  
    bucket_sort(a)  
    print(a) # [2, 3, 3.2, 4, 6, 6, 7, 8]  

10、基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

基数排序 vs 计数排序 vs 桶排序

基数排序有两种方法:

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

  • 基数排序:根据键值的每位数字来分配桶;

  • 计数排序:每个桶只存储单一键值;

  • 桶排序:每个桶存储一定范围的数值;

动图演示

Python 代码

def RadixSort(list):  
    i = 0                                    #初始为个位排序  
    n = 1                                     #最小的位数置为1(包含0)  
    max_num = max(list) #得到带排序数组中最大数  
    while max_num > 10**n: #得到最大数是几位数  
        n += 1  
    while i < n:  
        bucket = {} #用字典构建桶  
        for x in range(10):  
            bucket.setdefault(x, []) #将每个桶置空  
        for x in list: #对每一位进行排序  
            radix =int((x / (10**i)) % 10) #得到每位的基数  
            bucket[radix].append(x) #将对应的数组元素加入到相 #应位基数的桶中  
        j = 0  
        for k in range(10):  
            if len(bucket[k]) != 0: #若桶不为空  
                for y in bucket[k]: #将该桶中每个元素  
                    list[j] = y #放回到数组中  
                    j += 1  
        i += 1  
return  list

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32入门基础

GPIO <1>说明 引脚电平&#xff1a;0~3.3V&#xff0c;部分可达到5V(参考引脚定义&#xff0c;带FT的就可以) 同时 GPIO有两个模式 输出模式&#xff1a;进行端口高低电平的输出&#xff0c;用于驱动LED&#xff0c;蜂鸣器等 输入模式&#xff1a;读取端口高低电平…

SimBERT剖析

SimBERT SimBERT&#xff0c;它是以Google开源的BERT模型为基础&#xff0c;基于微软的UniLM思想设计了融检索与生成于一体的任务&#xff0c;来进一步微调后得到的模型&#xff0c;所以它同时具备相似问生成和相似句检索能力。 UniLM UniLM是一个融合NLU和NLG能力的Transfo…

远程桌面控制:SmartCode VNC ViewerX ActiveX 3.10 Crack

SmartCode::ViewerX VNC 查看器 ActiveX 毫不费力地将 VNC 查看器功能添加到您的应用程序 SmartCode ViewerX VNC 查看器 ActiveX 使开发人员可以使用一组直观的 ActiveX 属性和方法完全访问 VNC 查看器功能。借助ViewerX 控件&#xff0c;开发人员可以轻松地为其应用程序提供屏…

将自己写的代码利用git 上传到码云(gitee)或者github----最简洁明了版

前置操作 注册并激活码云账号&#xff08; 注册页面地址&#xff1a;https://gitee.com/signup &#xff09; 生成并配置 SSH 公钥 官方提供的生成并配置公钥的方法点此 创建空白的码云仓库 输入仓库名称之后路径会自动生成 把本地项目上传到码云对应的空白仓库中 如果您是…

MyBatis-Plus快速开始

文章目录介绍特性框架结构传统编程模式快速开始介绍 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。只做增强不做改变的意思是&#xff1a;MP不会影响原生的 M…

[HITCON 2017]SSRFme(perl脚本中get命令执行漏洞)

目录 代码审计 思路 知识补充 PHP中$_SERVER的详细用法 pathinfo() 函数 str_replace() 函数 escapeshellarg peal函数中get命令漏洞 Perl中open命令执行&#xff08;GET&#xff09; 代码审计 <?phpif (isset($_SERVER[HTTP_X_FORWARDED_FOR])) {$http_x_headers…

GuLi商城-项目初始结构创建

GitHub账号和密码 账号&#xff1a;11360XXXXXqq.com 密码&#xff1a;ZH**SH*19**1016 新建仓库&#xff1a; gulimall 记得勾选下Add a README file&#xff0c;上面忘记勾选了&#xff0c;实际建议还是要勾选下 复制路径&#xff1a; 打开IDEA检出项目 创建商品微服务模…

flutter 作为模块引入 iOS 项目

原文 http://summerxx.com/2023/01/28/ios-use-flutter/ 前言: 上篇我讲了下 flutter 环境在 MacOs 下搭建, 今天写下如何在一个成熟的 iOS 项目内引用 flutter, Demo 会放到文章最后哈 上篇 : MacOS 下配置flutter 环境 大致如下: 在项目内创建一个 flutter 模块 新建一个 …

Unity 在URP中显示动态批处理 Dynamic Batching 选项

Unity 在URP中显示动态批处理 Dynamic Batching 选项前言步骤1. 打开 Preferences 设置2. 选择 Core Render Pipeline 选项卡3. 修改 Visibility 为 All Visible4. 打开 Project Settings5. 打开 Graphics 选项卡6. 找到 URP 设置7. 开启 Dynamic Batching鸣谢前言 使用URP时突…

计算机相关专业提升学历的解决方案(本科及以下)

文章目录1、学历与学位的区别1.1 学历与学位的概念&#xff0c;学籍的规则1.2 学历与学位的作用2、正规全日制本科2.1 高考2.2 统招专升本3、继续教育&#xff08;非全日制&#xff09;3.1 自学考试&#xff08;无学籍&#xff09;3.2 成人高考&#xff08;函授&#xff0c;业余…

详谈ORB-SLAM2的跟踪线程Tracking

ORB-SLAM2的三大线程几乎都是每个部分对应一个函数&#xff0c;非常清晰。函数名起的都十分贴切&#xff0c;望文就能生义&#xff0c;我们更应该关注的是里面的关键帧地图点这些变量是怎么流转的。 Tracking线程的流程就是&#xff1a;首先输入一帧图像&#xff0c;然后实际上…

开启前端CSS学习之路-css003

&#x1f60a;博主页面&#xff1a;鱿年年 &#x1f449;博主推荐专栏&#xff1a;《WEB前端》&#x1f448; ​&#x1f493;博主格言&#xff1a;追风赶月莫停留&#xff0c;平芜尽处是春山❤️ 目录 CSS引入方式 一、CSS的三种样式表 1.内部样式表 2.行内样式表 3.外…

用java判断闰年

闰年的判断&#xff1a; 能被400整除的年份是闰年能被4整除的但是不能被100整除的年份是闰年 import java.util.Scanner; public class leapYear{public static void main(String[] args){int year;Scanner sc new Scanner(System.in);year sc.nextInt();if((year % 400 0)…

Java中对象的比较

从大根堆说到对象的比较大小根堆对象的比较equalsComparableComparator大小根堆 大小根堆是堆相关的知识,堆这种数据结构总结起来就是:堆顶元素是最大的就是大根堆,而每个堆顶元素以下的又可以看成一个堆: 要注意的是,堆底层是用数组实现的: 但是对这种数据结构具体化之后与…

JVM OOM和CPU问题排查

目录 1、JVM调优工具 1.1、jps 1.2、jstat 1.3、jstack 1.4、jinfo 1.5、jmap 2、OOM排查过程 2.1、OOM原因 2.2、OOM发生区域 2.2.1、Java堆溢出&#xff1a;heap 2.2.2、Java栈溢出&#xff1a;stack 2.2.3、运行时常量溢出&#xff1a;constant 2.2.4、方法区…

计算机毕业设计选题推荐nodejs+vue355的网上购物商城系统

网上购物商城&#xff0c;在系统首页可以查看首页、关于我们、商品信息、新闻信息、交流论坛、留言反馈、个人中心、后台管理、在线客服等内容 前端技术&#xff1a;nodejsvueelementui 前端&#xff1a;HTML5,CSS3、JavaScript、VUE 1、 node_modules文件夹(有npn install产…

spring整合mybatis的核心思路(数据源切换)

文章目录1. 整合思路2. 最简单的整合步骤1. 导入依赖2. 准备基础类UserUserMapperuserMapper.xmlMybatisConfig3. 测试TestMybatisSpring3. 整合多个mybatis配置1. 修改MybatisConfig2. 测试TestMybatisSpring4. AbstractRoutingDataSource实现源切换1. 准备基础类PersonPerson…

JVM的栈内存

每当启动一个新线程时&#xff0c;Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作&#xff1a;以帧为单位的压栈和出栈。 某个线程正在执行的方法被称为该线程的当前方法&#xff0c;当前方法使用的栈帧称为当前帧…

车载以太网 - SomeIP测试 - 初识 - 01

SOA,Service-Oriented Architecture,即面向服务的架构 SOA是一种面向服务的架构,定义了“服务器”和“客户端”,前者是服务、数据的提供者,后者是订阅了所需要的服务或者数据。应用程序之间是公三耦合,并通过服务总线作为中间件进行通信。SOA更像是一种框架,需要将信息从…

【JavaGuide面试总结】Java集合篇·下

【JavaGuide面试总结】Java集合篇下1.HashMap 的长度为什么是 2 的幂次方2.HashMap 有哪几种常见的遍历方式?3.HashSet 如何检查重复?4.ConcurrentHashMap 和 Hashtable 的区别5.ConcurrentHashMap 线程安全的具体实现方式/底层具体实现JDK1.8 之前JDK1.8 之后6.JDK 1.7 和 J…