JAVA面试题第九天

    xiaoxiao2025-03-01  34

    今天是第九天。 1.什么是线程池(thread pool)? 答:在面向对象编程中,创建和销毁对象是一件耗费时间的事情,创建一个对象的时候需要去操作内存资源或者更多的资源,在java中更是如此,虚拟机总是试图跟踪每一个对象,然后在对象销毁的时候进行垃圾回收。所以提高服务程序的效率就需要降低一些对象的创建和销毁,特别是耗费资源的对象的创建和销毁。所谓的线程池,就是事先创建一些可执行的线程放入一个容器中,然后等到需要的时候就直接从容器中拿取,不用的时候在放回池中,减少了线程中对象的创建和销毁。

    2.线程的状态以及状态的基本联系? 其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。

    3.简述synchronized和java.util.concurrent.locks.lock的异同? Lock能完成synchronized所实现的功能,不同点是,lock有更精确的线程语义和 更好的性能,lock不一定要获得锁,synchronized会自动释放锁,而lock一定要程序员来释放,最好在finally中( 这是释放外部资源最好的地方)。

    4.java中如何实现序列化,有什么意义。 序列化就是一种处理对象流的机制,所谓的对象流就是对对象的内容进行流化,然后可以对流化后的对象进行读写操作,也可以将流化后的对象进行网络传输。序列化是为了解决对象读写操作时可能存在的一些问题如数据乱序。要实现序列化,必须让对象的类实现一个serialiable接口,这是一个标识型接口,表示该对象可以序列化,使用一个输出流来构造对象输入流,在通过writeObject就可以实现对象写出,要实现反序列化,可以通过一个输出流构造一个对象输出流,在通过readObject方法就可以从流中读取对象数据了。序列化除了可以实现对象的持久化以外,还可以实现对象的深度克隆。

    5.java中有几种类型的流。 有字节流和字符流。字节流继承与inputStream和outputStream,字符流继承与reader和Writer。在java.io还有其他的流,主要是为了提高性能了方便性。使用流需要注意的是对称性和两种设计模式。

    编程实现文件拷贝:

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public final class MyUtil{ private MyUtil() { throw new AssertionError(); } pubic static void fileCopy(String source,String target) throw IOException { try(inputStream in = new FileInputStream(source)) { try(OutputStream out = new FileOutStream(target)) { byte[] buffer = new byte[4096]; int bytesToRoad; whilt(bytesToRoads = in.read(buffer)) != -1) { out.write(buffer,0,bytesToRead); } } } } public static void fileCopyNIO(String source, String target) throws IOException { try (FileInputStream in = new FileInputStream(source)) { try (FileOutputStream out = new FileOutputStream(target)) { FileChannel inChannel = in.getChannel(); FileChannel outChannel = out.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(4096); while(inChannel.read(buffer) != -1) { buffer.flip(); outChannel.write(buffer); buffer.clear(); } } } } }

    6.写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数。

    import java.io.BufferedReader; import java.io.FileReader; public final MyUtil { //工具类中方法都是静态方式访问的因此将构造器私有不允许创建对象(绝对好习惯) private MyUtil() { throw new AssertionError(); } } /** * *@param filename 文件名 *@param word 字符串 *@return 字符串在文件中出现的次数 **/ public static int countWordInFile(String filename,String word) { int counter = 0; try(FileReader fr = new FileReader(filename)) { try(BufferReader br = new BufferReader(fr)) { String line = null; while((line = br.readLine()) != null) { int index = -1; while(line.length()>=word.length() && (index = line.indexOf(word)>=0) { counter++; line = line.substring(index+word.length()); } } }catch(Exception ex) { ex.printStackTrace(); } return counter; }

    7.XMl文档定义有几种形式?它们之间有何本质区别?解析ML文档有哪几种方式?

    8.java是如何支持正则表达式操作的? 答:java中的String类提供支持表达式操作的方法,包括matches()、replaceAll()、replaceFirst()、split()。此外,java可以用pattern类表示正则表达式的对象,他提供了丰富的API进行各种正则表达式操作,请参考下面面试题代码 如果从字符串中截取第一个英文括号之前的字符串,怎么写

    public static void main(String[ ] args){ String str = "北京市(朝阳区)(西城区)(海淀区)"; Patter p = Pattern.compile(".*(?=\\())"); Matcher m = p.matcher(str); if(m.find()) { System.out.println(m.group()); } }

    先创建一个String类的对象,里面放要操作的字符串,使用patter的静态方法compile()返回一个pattern类型的结果p,使用p.matche返回一个Matcher类型的方法m。.find()如果大于0,m.group()就是截取的结果。

    9.获得一个类的类对象有哪些方式? (类对象什么用?) 答: 方法1:类型.class,例如:String.class 方法2:对象.getClass(),例如:“hello”.getClass(); 方法3:Class.forName(),例如Class.forName(“java.lang.String”)

    10.如何通过反射创建对象?(为什么要通过反射创建对象) 答: 方法1:通过类对象调用newInstance ()方法,String.class.newInstance() 方法2:通过类对象的getContructor()或getDeclaredContructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,例如:Stirng.class.getConstructor(String.class).newInstance(“Hello”);

    11.如何通过反射获取和设置对象私有字段的值? 答:可以通过类对象的getDelclaredFiled()方法字段(Filed)对象,然后再通过字段对象的setAccessible(ture)将其设置为可以访问,接下来就可以通过get/set方法获取/设置字段的值了。下面的代码

    import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; public class ReflerctionUtil { private RefilectionUtil() { throw new AssertionError(); } /** *通过反射取对象指定字段(属性)的值 *@param target 目标对象 *@param fieldName字段的名字 *@throws 如果取不到对象指定字段的值则抛出异常 *@return 字段的值 public static Object getValue(Object target,String fileName) { Class<?> clazz = target.getClass(); String[ ] fs = fieldName.spilt("\\."); try{ for(int i = 0;i<fs.length-1;i++) { Filed f = clazz.getDelcaredFiled(fs[i]); f.setAccessible(true); target = f.get(target); clazz = target.getClass(); } Filed f = clazz.getDeclaredFiled(fs[fs.length-1); f.setAccessible(ture); return f.get(target); } catch(Exception e) { throw new RuntimeException(e); } } /** *通过反射给对象的指定字段赋值 *@param target 目标对象 *@param filedName 字段的名称 *@param value 值 */ public static void setValue(Object target,String filedName,Object value) { Class<?> clazz = target.getClas(); String[] fs = filedName(split"\\."); try{ for(int i = 0;i<fs.length-1;i++) { FIled f = clazz.getDeclaredFiled(fs[i]); f.setAccessible(fs[i]); Object val = f.get(target); if(val == null){ Constructor<?> c = f.getType().getDeclaredContructor(); c.setAccessible(true); val = c.newInstance; f.set(target,val); } target = val; clazz = target.getClass(); } Field f = clazz.getDeclaredFiled(fs[fs.length-1]); fs.setAccessible(true); f.set(target,value); } catch(Exception e) { throw new RuntimeException(e); } } }
    最新回复(0)