当前位置: 首页 > 后端技术 > Java

Java面试题总结(每日更新2)

时间:2023-04-01 14:47:13 Java

Java基础21.Java安全语言级别的安全主要体现在:Java取消了强大但危险的指针,取而代之的是引用。由于指针是可以移动的,所以指针可以随意指向一块内存区域,而不管该区域是否可用。这是很危险的,因为原来的内存地址可能存放重要数据或者被其他程序占用,而且使用指针数组也很容易越界。垃圾回收机制:程序员无需直接控制内存回收,垃圾回收器在后台自动回收未使用的内存。防止程序忘记及时回收,导致内存泄漏。避免程序错误回收程序核心类库的内存,导致系统崩溃。异常处理机制:Java的异常机制主要依赖五个关键字:try、catch、finally、throw、throws。强制类型转换:只有满足强制转换规则才能强制转换成功。底层的安全性可以从以下几个方面来解释:Java在字节码的传输过程中使用了公钥加密机制(PKC)。在运行环境中提供了四级安全保障机制:字节码验证器-类加载器-运行时内存布局-文件访问限制)和微型版(J2ME)三个版本:标准版(StandardEdition)J2SE包含那些构成Java语言的核心。例如:数据库连接、接口定义、输入/输出、网络编程企业版(EnterpriseEdition)J2EE包括J2SE中的类,也包括用于开发企业应用程序的类。如servlet、JSP、XML、事务控制MicroEdition(微型版)J2ME包含了J2SE中的一些类,用于消费类电子产品的软件开发。例如:寻呼机、智能卡、移动电话、PDA和机顶盒。它们的范围是:J2SE包含在J2EE中,J2ME包含了J2SE的核心类,但增加了一些新的专有应用,API的覆盖范围各不相同。3.八种基本数据类型及其字节数4.大O表示法(big-Onotation)大O表示法描述了当数据结构中的元素增加时,算法的规模或性能处于最坏的情况多好啊。大O表示法也可以用来描述其他行为,例如内存消耗。因为集合类实际上是数据结构,所以我们一般使用大O表示法,根据时间、内存和性能来选择最佳实现。大O表示法可以很好地说明大量数据的性能。同时,大O表示法表示程序运行所需的渐近时间复杂度的上限。其函数表达式为:对于函数f(n),g(n),若存在常数c使得f(n)<=c*g(n),则f(n)=O(g(n));5。数组(Array)和列表(ArrayList)Array和ArrayList的区别:Array可以包含基本类型和对象类型,而ArrayList只能包含对象类型。Array的大小是固定的,ArrayList的大小是动态的。ArrayList提供了更多的方法和特性,例如:addAll()、removeAll()、iterator()等。对于原始类型,集合使用自动装箱来减少编码工作量。但是,这种方法在处理固定大小的原始数据类型时相对较慢。6.值传递和引用传递值传递是针对基本变量的,传递的是变量的副本。更改副本不会影响原始变量。引用传递一般是针对对象变量,传递的是对象地址的副本,而不是原始对象本身。因此,对引用对象的操作会同时改变原对象。一般认为java中的传递是值传递。7.基本数据类型的类型转换规则基本类型转换分为自动转换和强制转换。自动转换规则:小容量数据类型可以自动转换为大容量数据类型,或者低级自动转换为高级。这里的容量不是指字节数,而是指类型表示的范围。红色可能丢失精度强制规则:高级变为低级需要强制。如何转换:(1)赋值运算符“=”右边的转换,先自动转换为表达式中最高级别的数据类型,再进行运算。(2)对于赋值运算符“=”两边的转换,如果左层>右层,则自动转换;如果左电平==右电平,则不需要转换;如果左电平<右电平,则需要强制转换。(3)整型常量可以直接赋值给byte、short、char等类型变量,无需强制类型转换,前提是不超出表达式的范围,否则需要强制转换。8、计算2乘8最高效的方法是使用位运算,效率最高。位运算符以二进制位为单位对操作数进行运算和操作,操作数和结果都是整数。对于位运算符“<<”,就是将一个数左移n位,相当于乘以2的n次方。然后,要将一个数乘以8,只需将其左移3位即可。位运算cpu直接支持效率最高。所以,2乘8最高效的方式是2<<39。if和switch一样:都是分支语句,判断处理的情况不止一种。不同点:switch更适合多分支的情况,即需要判断处理的情况比较多。判断条件类型单一,只有一个入口。分支执行完后(如果没有break),不判断继续执行;if—elseif—else多分支主要适用于分支较少的分支结构,判断类型不单一。只要执行了一个分支,后面的分支就不会执行了。switch用于等价判断(例如>=<=是不允许的),而if用于等价和区间,if具有广泛的应用范围。10.递归的定义和优缺点递归算法是直接或间接调用自身算法的过程。在计算机程序设计中,递归算法对于解决一大类问题非常有效,它常常使算法的描述简洁易懂。递归算法求解问题的特点:(1)递归是在过程或函数中调用自身。(2)在使用递归策略时,必须有明确的递归结束条件,称为递归退出。(3)递归算法求解问题通常很简单,但运行效率低。所以一般不推荐使用递归算法来设计程序。(4)在递归调用过程中,系统开栈存储返回点和各层本地数量。递归过多容易造成栈溢出等。所以一般不推荐使用递归算法来设计程序。11.数组数组是同类数据的有序集合。数组会在内存中开辟一块连续的空间。每一个空格都相当于之前的一个变量。称为数组的元素的索引从0开始,每个数组元素都有一个默认值double0.0;布尔假;int0数组的元素是有序的,不是大小的顺序,而是索引的顺序。数组中可以存放基本数据类型和引用数据类型;但是对于数组来说,数组的类型是固定的,只能是一个长度:数组的长度。数组的长度是固定的。一旦定义,就不能再更改(数组的扩展)。在包装器类型之间完成的转换。例如:将int转换为Integer,将double转换为Double,等等。与之相反的是自动拆箱。13、为什么会有4.0-3.6=0.40000001原因很简单:二进制小数不能准确表示十进制小数,计算机在计算十进制小数的过程中必须先转为二进制进行计算,在这个过程中出现了错误。14.Lamda表达式的优缺点优点:简洁。非常容易并行化计算。可能代表未来的编程趋势。缺点:如果不使用并行计算,很多情况下计算速度并不比传统的for循环快。(并行计算有时需要预热才能显示出效率优势)不易调试。如果其他程序员没有学过lambda表达式,代码对于其他语言的程序员来说是不容易看懂的。15.Java8的新特性Lambda表达式-Lambda允许函数作为方法的参数(函数作为参数传递给方法。方法引用-方法引用提供了一种非常有用的语法,可以直接引用现有的Java类或对象(Instance)方法或构造函数。与lambda结合使用,方法引用可以使语言结构更加紧凑简洁,减少冗余代码。默认方法-默认方法是在接口中具有实现的方法。新工具-新编译工具,如:Nashorn引擎jjs,类依赖分析器jdepsStreamAPI-新增的StreamAPI(java.util.stream)将真正的函数式编程风格引入JavaDateTimeAPI-加强了日期与时间的处理可选类?可选类已成为Java8类库的一部分,用于解决空指针异常Nashorn,JavaScript引擎?Java8提供了一个新的Nashornjavascript引擎,它允许我们运行特定的javascript应用程序。16、符号“==”比较“==”,根据内存引用比较两个对象。如果两个对象的引用完全相同(指向同一个对象),则“==”操作返回true,否则返回false。“==”如果两边都是基本类型,就是比较值是否相等。17、如果Object不重写hashCode(),那么hashCode()如何计算Object?hashcode方法是本地方法,即使用c语言或c++实现,该方法直接返回对象的内存地址。18、为什么要重写equals和重写hashcodeHashMap,如果要比较key是否相等,必须同时使用这两个函数!因为自定义类的hashcode()方法是继承自Object类的,其hashcode是默认的内存地址,所以即使两个对象意义相同,比较起来也不相等。HashMap中的比较key是这样的,先找到key的hashcode(),比较它的值是否相等,如果相等,再比较equals(),如果相等,则认为相等。如果equals()不相等,则认为它们不相等。如果只重写hashcode(),不重写equals()方法,比较equals()时,只需要检查是否是同一个对象(即比较内存地址),所以必须同时重写两个方法。HashMap判断key是否相等的方法其实就是调用HashSet判断加入的元素是否相等。重载hashCode()就是对同一个key获取相同的HashCode,这样HashMap就可以定位到我们指定的key。重载equals()的目的是为了向HashMap表明当前对象和key上存储的对象是相等的,这样我们才能真正得到key对应的键值对。19、Map的分类及常见情况Java在数据结构中定义了一个接口java.util.Map用于映射;它有四个实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMap。Map主要用于存储键值对。根据key获取value,所以key不允许重复(repeatedandcovered),但是value允许重复。Hashmap是最常用的Map。它根据key的HashCode值存储数据,根据key可以直接获取其值。它具有快速的访问速度。遍历时,获取数据的顺序是完全随机的。HashMap最多只允许一条记录的key为Null;多条记录的值允许为Null;HashMap不支持线程同步,即多个线程随时可以同时写入HashMap;它可能会导致数据不一致。如果需要同步,可以使用Collections的synchronizedMap方法使HashMap同步,或者使用ConcurrentHashMap。Hashtable类似于HashMap,它继承自Dictionary类,不同的是:它不允许记录的key或value为空;它支持线程同步,即任何时刻只能有一个线程写入Hashtable,所以也导致Hashtable写入Entry会比较慢。LinkedHashMap是HashMap的子类,保存了记录的插入顺序。使用Iterator遍历LinkedHashMap时,必须先插入先得到的记录。也可以带参数构造,按照申请数量排序。遍历的时候会比HashMap慢,但是有个例外。当HashMap容量大而实际数据少时,遍历速度可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只与实际数据有关,与容量无关。HashMap的遍历速度与其容量有关。reeMap实现了SortMap接口,它可以根据键对它保存的记录进行排序。默认是键值升序排列,也可以指定排序比较器。在使用Iterator遍历TreeMap时,对得到的记录进行排序。一般来说,我们用的最多的是HashMap,在Map中插入、删除、定位元素,HashMap是最好的选择。但是,如果您想以自然顺序或自定义顺序遍历键,那么TreeMap会更好。如果要求输出的顺序和输入的顺序一致,可以使用LinkedHashMap,也可以按照读取的顺序排列。20、冒泡排序冒泡排序算法的原理是这样的:比较相邻的元素。如果第一个大于第二个,则交换它们。对每对相邻元素执行相同的操作,从开头的第一对到结尾的最后一对。此时,最后一个元素应该是最大的数。对除最后一个元素之外的所有元素重复上述步骤。每次对越来越少的元素继续重复上述步骤,直到没有要比较的数字对。publicclassBubble{publicint[]sort(int[]array){inttemp=0;//外层循环,它决定走多少次//-1以防止溢出for(inti=0;iarray[j]){temp=array[j];数组[j]=数组[j+1];数组[j+1]=温度;标志=1;}}if(flag==0){中断;}}返回数组;}publicstaticvoidmain(String[]args){Bubblebubble=newBubble();int[]array={2,5,1,6,4,9,8,5,3,1,2,0};int[]sort=bubble.sort(array);for(intnum:sort){System.out.print(num+"\t");}}}