Java基础31.选择排序选择排序(Selectionsort)是一种简单直观的排序算法。它的工作原理是每次从待排序的数据元素中选择最小(或最大)的元素,存入序列的起始位置,然后继续从剩余未排序的元素中寻找最小(或最大)的元素,并放在排序序列的末尾。以此类推,直到所有需要排序的数据元素都用完。选择排序是一种不稳定的排序方法。publicclassSelectSort{publicint[]sort(intarr[]){inttemp=0;for(inti=0;iarr[j]){//修改最小值的下标minIndex=j;}}}}//exitfor这次找到最小值的时候,需要交换位置if(i!=minIndex){//交换当前值和找到的最小值的位置temp=arr[i];arr[i]=arr[最小索引];arr[minIndex]=温度;}}}返回arr;}publicstaticvoidmain(String[]args){SelectSortselectSort=newSelectSort();int[]array={2,5,1,6,4,9,8,5,3,1,2,0};int[]sort=selectSort.sort(数组);for(intnum:sort){System.out.print(num+"\t");}}}2.插入排序有一个已经有序的数据序列。要求在这个已经排好序的数据序列中插入一个数,但要求插入后数据序列还是有序的。这时,要用到一种新的排序方法——插入排序方法,插入排序的基本操作是在已经排序好的有序数据中插入一条数据,从而得到一个新的有序数据,其个数增加了一、该算法适用于对少量数据进行排序,时间复杂度为O(n^2)。是一种稳定的排序方法。插入算法将待排序的数组分为两部分:第一部分包含数组的所有元素,除了最后一个元素(让数组多出一个空间插入),而第二部分只包含这一个元素(即要插入的元素)。第一部分排序后,将最后一个元素插入排序的第一部分。插入排序的基本思想是:每一步根据其键码值的大小,将一条待排序记录插入到之前排序文件中的合适位置,直到全部插入。包括:直接插入排序、二分插入排序(又称二分插入排序)、链表插入排序、希尔排序(又称收缩增量排序)。是一种稳定排序(通俗地说,两个相等的数不会交换位置)。一般来说,插入排序是在数组上使用原地实现的。具体算法描述如下:1.从第一个元素开始,可以认为该元素已排序。2.取出下一个元素,在排序好的元素序列中从后往前扫描。3.如果元素(已排序)大于新元素,则将该元素移动到下一个位置4.重复步骤3,直到找到已排序元素小于等于新元素的位置如果,则二分查找方法可用于减少比较操作的次数。该算法可以被认为是插入排序的变体,称为二进制搜索排序。publicclassInsertSort{privateint[]sort(int[]arr){//如果传入的数组为空或者只有一个值,直接返回if(arr==null||arr.length<2){returnarr;}//不为空则进入循环判断//外循环控制总数for(inti=1;i0;j--){[j]=arr[j-1];arr[j-1]=温度;}else{休息;}}}返回arr;}publicstaticvoidmain(String[]args){InsertSortinsertSort=(new);int[]array={2,5,1,6,4,9,8,5,3,1,2,0};int[]sort=insertSort.sort(数组);for(intnum:sort){System.out.print(num+"\t");}}关键字4.final关键字当一个类被final修饰时,表示该类不能被继承。也就是说,如果你永远不会让一个类被继承,你可以用final来修饰它。final类中的成员变量可以根据需要设置为final,但需要注意的是final类中的所有成员方法都会被隐式指定为final方法。“使用final方法有两个原因,第一个原因是锁定方法,防止任何继承类修改其含义;第二个原因是效率。在早期的Java实现版本中,final方法被转换为Inline调用。但如果方法太大,您可能看不到内联调用带来的任何性能提升。在最近的Java版本中,不需要为这些优化使用final方法。“对于final变量,如果是基本数据类型的变量,一旦初始化就不能改变其值;如果是引用类型的变量,则初始化后不能使其指向另一个对象。5.synchronized和locksynchronized是Java中的关键字,当它们用于修饰一个方法或者一个代码块时,可以保证最多有一个线程同时执行这段代码。JDK1.5引入了自旋锁和锁粗化,轻量级锁,偏向于锁来优化关键字的性能。Lock是一个接口,而synchronized是Java中的一个关键字,synchronized是一种内置的语言实现;当异常发生时,synchronized会自动释放线程持有的锁,所以不会导致死锁;而当Lock发生异常时,如果不主动通过unLock()释放锁,很可能会造成死锁,所以在使用Lock时,需要在Lock中释放锁finallyblock;Lock可以让等待锁的线程响应中断,而synchronized不行。使用synchronized时,等待线程会一直等待,无法响应中断;通过Lock可以知道锁是否已经成功获取,而synchronized做不到。6.volatile关键字用于保证顺序和可见性。这与Java内存模型有关。比如我们写的代码不一定按照我们写的顺序执行,编译器会做重排序,CPU也会做重排序,这种重排序是为了减少流水线的阻塞,造成流水线的阻塞流水线,如数据关联,提高CPU的执行效率。需要有一定的顺序和规则来保证,不然程序员自己写的代码不知道对不对,所以就有了happens-before规则,其中之一就是volatile变量规则:写操作到变量首先出现在对变量的读取操作之前;顺序是通过插入一个内存屏障来保证的。可见性:首先,Java内存模型分为主内存和工作内存。比如线程A从主存中读取变量到自己的工作内存中并加1,但是并没有将i的最新值刷新到主存中,此时线程B仍然读取的是i的旧值。带volatile关键字的代码生成的汇编代码发现会多出一条lock前缀指令。对于Intel平台的CPU,早期使用Lock指令来锁定总线,代价太大。后来又提出了缓存一致性协议MESI来保证多核之间的数据不一致。7.syncronizedlock,如果用这个关键字修饰一个静态方法,锁的是什么?如果修改了成??员方法,锁定的是什么?synchronized修饰的静态方法和synchronized代码块的synchronized(class.class)用法锁住类。如果线程要执行相应的同步代码,就需要获得类锁。synchronized修改成员方法,线程获取当前调用该方法的对象实例的对象锁。8.封装继承多态封装封装是将一个对象的属性私有化,并提供一些属性的方法可以被外界访问。如果属性不想被外界访问,我们就不必提供方法让外界访问。但是如果一个类不提供外部访问的方法,那么这个类就没有意义。继承继承是一种使用现有类的定义作为基础来创建新类的技术。新类的定义可以添加新数据或新函数,也可以使用父类的函数,但不能有选择地继承父类。通过使用继承,我们可以轻松地重用以前的代码。请记住以下关于继承的三点:子类拥有父类的非私有属性和方法。子类可以有自己的属性和方法,即子类可以扩展父类。子类可以按照自己的方式实现父类的方法。(稍后介绍)。多态性所谓多态性,是指程序中定义的引用变量所指向的具体类型,以及通过引用变量发出的方法调用,并不是在编程时就确定的,而是在程序运行时确定的。指向哪个类的实例对象,引用变量发出的方法调用是在哪个类中实现的方法,这是程序运行过程中必须确定的。Java中的多态有两种形式:继承(多个子类重写同一个方法)和接口(实现一个接口并重写接口中的同一个方法)。9、空参构造方法的作用Java程序在执行子类的构造方法之前,如果不使用super()调用父类的具体构造方法,则调用中的“无参构造方法”父类将被调用。因此,如果父类中只定义了带参数的构造函数,而在子类的构造函数中没有使用super()调用父类中的具体构造函数,编译时就会出错,因为Java程序中的在父类中找不到执行的无参数构造函数。解决办法是在父类中添加一个什么都不做、没有参数的构造函数。10.接口和抽象类的区别。接口方法默认是public的,不能在接口中实现所有方法(Java8开始接口方法可以有默认实现),抽象类可以有非抽象方法。接口中默认的实例变量是final类型,而在抽象类中,不一定一个类可以实现多个接口,最多只能实现一个抽象类。如果一个类实现了一个接口,则必须实现该接口的所有方法,而抽象类不一定有不能用new实例化的接口,但可以声明,但必须引用一个实现该接口的对象。从设计层面来说,抽象是类的抽象,是模板设计,接口是行为的抽象,是行为的规范。11、成员变量和局部变量的区别从语法形式上来说,成员变量属于类,而局部变量是定义在方法中或者方法的参数中的变量;成员变量可以被public、private、static等修饰符修饰,而局部变量不能被访问控制修饰符和static修饰;但是,成员变量和局部变量可以被final修饰;从变量在内存中存储的角度来看,成员变量是对象的一部分,而对象存在于堆内存中,局部变量存在于栈内存中从变量在内存中的生命周期来看,成员变量是对象的一部分,随着对象的创建而存在,而局部变量随着方法调用而自动消失。如果成员变量没有赋初值,则自动赋该类型的默认值(在一种情况下,被final修饰的成员变量也必须显式赋值);不会自动分配局部变量。12.线程、程序、进程的基本概念和关系。进程是程序的一个执行过程,是系统运行程序的基本单位,所以进程是动态的。在系统中运行一个程序,就是一个进程从创建、运行到死亡的过程。简单来说,进程就是在计算机中一个接一个地执行指令的执行程序。同时,每个进程也占用一定的系统资源,如CPU时间、内存空间、文件、文件、设备的输入输出访问等。操作系统。线程类似于进程,但线程是比进程更小的执行单元。一个进程在执行期间可以产生多个线程。与进程不同的是,同类型的多个线程共享同一块内存空间和一组系统资源,因此系统在生成线程或线程间切换时,负担要比进程小很多。因此,线程也称为轻量级进程。程序是存储在磁盘或其他数据存储设备上的包含指令和数据的文件,也就是说程序是静态代码。线程是进程被划分成的较小的执行单元。线程和进程最大的区别就是每个进程基本都是独立的,但是每个线程就不一定了,因为同一个进程中的线程很有可能会相互影响。从另一个角度来说,进程属于操作系统的范畴,主要是在同一时间段内,可以同时执行多个程序,而一个线程几乎同时执行在同一个程序中的不止一个一个节目片段。13、可变参数的作用和特点总结1:可变参数可变参数的形式...可变参数只能是方法的形式参数。可变参数对应的实参可以是0,1,2.....n,也可以是数组在可变参数方法中,将可变参数当作数组来处理。最多有一个可变参数,并且只能是最后一个可变参数。好处:方便简单,减少重载方法的数量如果定义了可变参数方法,则不允许同时定义同类型数组参数的方法。可变参数的本质是把差值当成一个数组来处理:不同数量的可变参数只能有一个数组参数可以有多个位置不同的可变参数只能是最后一个数组参数位置任意实参不同的可变参数实参可以是0,1,2.....也可以是数组,数组的实参只能是数组privatestaticintsum(int...values){intsum=0;对于(inti=0;i