Java高频面试代码题(含可运行代码+详细解析)_第1页
Java高频面试代码题(含可运行代码+详细解析)_第2页
Java高频面试代码题(含可运行代码+详细解析)_第3页
Java高频面试代码题(含可运行代码+详细解析)_第4页
Java高频面试代码题(含可运行代码+详细解析)_第5页
已阅读5页,还剩6页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java高频面试代码题(含可运行代码+详细解析)本次面试题甄选Java后端初级、中级高频手写代码考题,涵盖基础语法、字符串、数组、集合、算法、多线程基础、异常、常用工具方法等核心考点,所有代码可直接编译运行,答案解析贴合企业面试评分标准,语言通俗、无书面化套话。一、基础语法与字符串面试题(必考)1.手写字符串反转(不使用自带reverse方法)题目要求:自定义方法实现字符串反转,支持普通字符串、空字符串,不调用StringBuilder/reverse自带反转方法面试考察点:字符数组遍历、字符串底层逻辑、边界值处理java

publicclassStringReverse{

//手动实现字符串反转

publicstaticStringreverse(Stringstr){

//边界处理:空值、空字符串直接返回

if(str==null||str.length()==0){

returnstr;

}

char[]chars=str.toCharArray();

intleft=0;

intright=chars.length-1;

//双指针首尾交换

while(left<right){

chartemp=chars[left];

chars[left]=chars[right];

chars[right]=temp;

left++;

right--;

}

returnnewString(chars);

}

publicstaticvoidmain(String[]args){

System.out.println(reverse("hellojava"));//输出:avajolleh

System.out.println(reverse(""));//输出空字符串

System.out.println(reverse(null));//输出null

}

}详细答案解析:1.优先做边界判断,避免空指针异常和数组越界,这是面试重点加分项;2.采用双指针交换字符,时间复杂度O(n),效率高于逐位拼接;3.相比递归反转,该方法无栈溢出风险,适合长字符串场景。2.判断字符串是否为回文字符串题目要求:判断一个字符串正读和反读是否一致,忽略大小写面试考察点:双指针用法、字符串大小写处理、逻辑严谨性java

publicclassPalindrome{

publicstaticbooleanisPalindrome(Stringstr){

if(str==null||str.length()==0){

returntrue;

}

//统一转为小写,忽略大小写差异

StringlowerStr=str.toLowerCase();

intleft=0;

intright=lowerStr.length()-1;

while(left<right){

if(lowerStr.charAt(left)!=lowerStr.charAt(right)){

returnfalse;

}

left++;

right--;

}

returntrue;

}

publicstaticvoidmain(String[]args){

System.out.println(isPalindrome("AbBa"));//true

System.out.println(isPalindrome("Java"));//false

}

}详细答案解析:1.空字符串和null默认判定为回文,符合业务常规逻辑;2.统一转小写,避免大小写干扰判断;3.双指针从首尾向中间遍历,只要出现字符不相等直接返回false,节省遍历时间。二、数组与基础算法面试题(高频手写)1.数组去重(普通数组,不使用集合工具类)题目要求:对int数组手动去重,返回新数组,不借助HashSet、ArrayList等集合工具面试考察点:数组遍历、元素比对、新数组组装java

publicclassArrayDistinct{

publicstaticint[]distinct(int[]arr){

//边界判断

if(arr==null||arr.length==0){

returnnewint[0];

}

//记录不重复元素个数

intcount=1;

for(inti=1;i<arr.length;i++){

booleanisRepeat=false;

for(intj=0;j<i;j++){

if(arr[i]==arr[j]){

isRepeat=true;

break;

}

}

if(!isRepeat){

count++;

}

}

//组装新数组

int[]newArr=newint[count];

intindex=0;

for(inti=0;i<arr.length;i++){

booleanisRepeat=false;

for(intj=0;j<index;j++){

if(arr[i]==newArr[j]){

isRepeat=true;

break;

}

}

if(!isRepeat){

newArr[index++]=arr[i];

}

}

returnnewArr;

}

publicstaticvoidmain(String[]args){

int[]arr={1,2,2,3,3,3,4};

int[]res=distinct(arr);

for(intnum:res){

System.out.print(num+"");//输出:1234

}

}

}详细答案解析:1.分两次遍历数组,第一次统计不重复元素数量,确定新数组长度;2.第二次遍历筛选元素,将不重复元素存入新数组;3.纯底层数组实现,面试中可体现基础功底,区别于工具类偷懒写法。2.二分查找(有序数组)题目要求:手写二分查找,实现有序数组目标元素查找,返回下标,无元素返回-1面试考察点:算法思想、循环边界处理、溢出问题java

publicclassBinarySearch{

publicstaticintbinarySearch(int[]arr,inttarget){

if(arr==null||arr.length==0){

return-1;

}

intleft=0;

intright=arr.length-1;

while(left<=right){

//避免left+right溢出,不使用(left+right)/2

intmid=left+(right-left)/2;

if(arr[mid]==target){

returnmid;

}elseif(arr[mid]>target){

//目标在左侧,右指针左移

right=mid-1;

}else{

//目标在右侧,左指针右移

left=mid+1;

}

}

return-1;

}

publicstaticvoidmain(String[]args){

int[]arr={1,3,5,7,9,11};

System.out.println(binarySearch(arr,7));//输出3

System.out.println(binarySearch(arr,2));//输出-1

}

}详细答案解析:1.核心优化:用left+(right-left)/2代替(left+right)/2,避免两个大数相加溢出;2.循环条件为left<=right,防止遗漏最后一个元素;3.时间复杂度O(logn),是有序数组最优查找方式。三、Java集合高频代码题1.ArrayList去重(两种实战写法)题目要求:实现ArrayList字符串去重,手写两种常用方式java

importjava.util.ArrayList;

importjava.util.HashSet;

importjava.util.List;

publicclassListDistinct{

//方式1:HashSet去重(简洁高效)

publicstaticList<String>distinctBySet(List<String>list){

if(list==null){

returnnewArrayList<>();

}

HashSet<String>set=newHashSet<>(list);

returnnewArrayList<>(set);

}

//方式2:遍历判断去重(不依赖Set,纯遍历)

publicstaticList<String>distinctByLoop(List<String>list){

if(list==null){

returnnewArrayList<>();

}

List<String>newList=newArrayList<>();

for(Strings:list){

if(!newList.contains(s)){

newList.add(s);

}

}

returnnewList;

}

publicstaticvoidmain(String[]args){

List<String>list=newArrayList<>();

list.add("java");

list.add("mysql");

list.add("java");

System.out.println(distinctBySet(list));//[java,mysql]

System.out.println(distinctByLoop(list));//[java,mysql]

}

}详细答案解析:1.HashSet去重:利用Set元素唯一性,代码简洁,效率高,适合大多数业务场景;2.遍历去重:不依赖其他集合,底层逻辑清晰,适合面试手写基础考察;3.两种方式均做了空集合判断,避免空指针异常。2.HashMap遍历的4种常用方式(面试必背)java

importjava.util.HashMap;

importjava.util.Map;

importjava.util.Set;

publicclassMapIterate{

publicstaticvoidmain(String[]args){

Map<String,Integer>map=newHashMap<>();

map.put("java",80);

map.put("mysql",85);

map.put("linux",90);

//方式1:entrySet遍历(效率最高,推荐)

System.out.println("entrySet遍历:");

for(Map.Entry<String,Integer>entry:map.entrySet()){

System.out.println(entry.getKey()+"="+entry.getValue());

}

//方式2:keySet遍历(二次取值,效率低)

System.out.println("\nkeySet遍历:");

Set<String>keys=map.keySet();

for(Stringkey:keys){

System.out.println(key+"="+map.get(key));

}

//方式3:values遍历(只取value)

System.out.println("\nvalues遍历:");

for(Integervalue:map.values()){

System.out.println(value);

}

//方式4:lambda遍历(JDK8+)

System.out.println("\nlambda遍历:");

map.forEach((k,v)->System.out.println(k+"="+v));

}

}详细答案解析:1.优先使用entrySet遍历,一次性获取键值对,无需二次查询,数据量大时优势明显;2.keySet方式每次get(key)都会查询哈希表,效率较低,不推荐大数据量使用;3.lambda写法简洁,适合日常开发,面试中需掌握四种方式区别。四、多线程基础代码面试题1.三种创建线程的方式(手写完整代码)面试考察点:线程基础、三种实现方式区别、启动原理java

//方式1:继承Thread类

classMyThreadextendsThread{

@Override

publicvoidrun(){

System.out.println("继承Thread类实现线程:"+Thread.currentThread().getName());

}

}

//方式2:实现Runnable接口

classMyRunnableimplementsRunnable{

@Override

publicvoidrun(){

System.out.println("实现Runnable接口实现线程:"+Thread.currentThread().getName());

}

}

publicclassThreadCreate{

publicstaticvoidmain(String[]args){

//启动Thread线程

newMyThread().start();

//启动Runnable线程

newThread(newMyRunnable()).start();

//方式3:匿名内部类线程(简化写法)

newThread(()->{

System.out.println("lambda线程:"+Thread.currentThread().getName());

}).start();

}

}详细答案解析+面试延伸:1.继承Thread类:无法再继承其他类,扩展性差,不推荐;2.实现Runnable接口:避免单继承限制,代码解耦,复用性强,主流写法;3.线程必须调用start()方法启动,不能直接调用run(),直接调用只是普通方法执行,不会开启新线程。2.手写synchronized实现线程安全(卖票案例)题目要求:解决多线程售票超卖、重复售卖问题java

publicclassTicketSaleimplementsRunnable{

//总票数

privateintticket=10;

@Override

publicvoidrun(){

//循环卖票

while(true){

//同步锁,保证同一时间只有一个线程执行

synchronized(this){

if(ticket<=0){

break;

}

System.out.println(Thread.currentThread().getName()+"卖出第"+ticket+"张票");

ticket--;

}

}

}

publicstaticvoidmain(String[]args){

TicketSaleticketSale=newTicketSale();

//三个线程同时卖票

newThread(ticketSale,"窗口1").start();

newThread(ticketSale,"窗口2").start();

newThread(ticketSale,"窗口3").start();

}

}详细答案解析:1.多线程共享同一个ticket变量,存在线程安全问题,通过synchronized锁住共享对象解决;2.锁代码块比锁方法粒度更细,执行效率更高;3.保证票数递减原子性,避免超卖、重复售票的并发问题。五、异常与基础实操面试题1.手动抛出异常+自定义异常题目要求:自定义业务异常,实现参数校验异常抛出java

//自定义业务异常

classBusinessExceptionextendsException{

publicBusinessException(Stringmsg){

super(msg);

}

}

publicclassExceptionTest{

//校验年龄

publicstaticvoidcheckAge(intage)throwsBusinessException{

if(age<0||age>150){

//手动抛出异常

throwne

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论