java开发岗位面试题汇总及解析2

二、Java IO
1. 讲讲IO里面的常见类,字节流、字符流、接口、实现类、方法阻塞。
答:
1)所有输入流类都是抽象类InputStream(字节输入流),或者抽象类Reader(字符输入流)的子类;
而所有输出流都是抽象类OutputStream(字节输出流)或者Writer(字符输出流)的子类。
2)
IO流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
字节流:一次读入或读出是8位二进制。
字符流:一次读入或读出是16位二进制。
结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。
输入流和输出流
输入流只能进行读操作,输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
输入字节流 InputStream
InputStream 是所有的输入字节流的父类,它是一个抽象类。
ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。
PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。
ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)。
输出字节流 OutputStream
OutputStream 是所有的输出字节流的父类,它是一个抽象类。
ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。
PipedOutputStream 是向与其它线程共用的管道中写入数据。
ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。
总结:
输入流:InputStream或者Reader:从文件中读到程序中;
输出流:OutputStream或者Writer:从程序中输出到文件中;
3)传统的阻塞式IO,每个连接必须要开一个线程来处理,并且没处理完线程不能退出。
假设当前有10000个连接,非阻塞方式可能用1000个线程的线程池就搞定了,而传统阻塞方式就需要开10000个来处理。如果连接数较多将会出现资源不足的情况
InputStream的read方法在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞
之前看过的忘得一干二净了。。。参考另外参考一篇blog,讲的不错,主要分析的是网络编程
传统IO方式(BIO)在调用InputStream.read()/buffer.readLine()方法时是阻塞的,它会一直等到数据到来或缓冲区已满时或超时时才会返回,并且产生了大量String类型垃圾,尽管可以使用StringBuffer优化;同样,在调用ServerSocket.accept()方法时,也会一直阻塞到有客户端连接才会返回,每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求。并且多线程处理多个连接。每个线程拥有自己的栈空间并且占用一些 CPU 时间。每个线程遇到外部未准备好的时候,都会阻塞掉。阻塞的结果就是会带来大量的进程上下文切换。且大部分进程上下文切换可能是无意义的。比如假设一个线程监听某一个端口,一天只会有几次请求进来,但是该 cpu 不得不为该线程不断做上下文切换尝试,大部分的切换以阻塞告终。
2. 讲讲NIO。
答:
核心类:
1.Buffer 为所有的原始类型提供 (Buffer) 缓存支持。
2.Charset 字符集编码解码解决方案
3.Channel 一个新的原始 I/O 抽象,用于读写Buffer类型,通道可以认为是一种连接,可以是到特定设备,程序或者是网络的连接
PS:BIO\NIO\AIO分析
3. String 编码UTF-8 和GBK的区别?
答:
GBK编码专门用来解决中文编码的,是双字节的。不论中英文都是双字节的。
UTF-8 编码是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对于英文字符较多的论坛则用UTF-8 节省空间。另外,如果是外国人访问你的GBK网页,需要下载中文语言包支持。访问UTF-8编码的网页则不出现这问题。可以直接访问。
4. 什么时候使用字节流、什么时候使用字符流?
答:
只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。
5. 递归读取文件夹下的文件,代码怎么实现
答:主要分递归或非递归
先进先出queue存储或者后进先出的stack存储
1)递归

private static void test(String fileDir) {  
        List<File> fileList = new ArrayList<File>();  
        File file = new File(fileDir);  
        File[] files = file.listFiles();// 获取目录下的所有文件或文件夹  
        if (files == null) {// 如果目录为空,直接退出  
            return;  
        }  
        // 遍历,目录下的所有文件  
        for (File f : files) {  
            if (f.isFile()) {  
                fileList.add(f);  
            } else if (f.isDirectory()) {  
                System.out.println(f.getAbsolutePath());  
                test(f.getAbsolutePath());  
            }  
        }  
        for (File f1 : fileList) {  
            System.out.println(f1.getName());  
        }  
    } 

2)非递归

   public void traverseFolder1(String path) {
        int fileNum = 0, folderNum = 0;
        File file = new File(path);
        if (file.exists()) {
            LinkedList<File> list = new LinkedList<File>();
            File[] files = file.listFiles();
            for (File file2 : files) {
                if (file2.isDirectory()) {
                    System.out.println("文件夹:" + file2.getAbsolutePath());
                    list.add(file2);
                    foldeNum++;
                } else {
                    System.out.println("文件:" + file2.getAbsolutePath());
                    fileNum++;
                }
            }
            File temp_file;
            while (!list.isEmpty()) {
                temp_file = list.removeFirst();
                files = temp_file.listFiles();
                for (File file2 : files) {
                    if (file2.isDirectory()) {
                        System.out.println("文件夹:" + file2.getAbsolutePath());
                        list.add(file2);
                        folderNum++;
                    } else {
                        System.out.println("文件:" + file2.getAbsolutePath());
                        fileNum++;
                    }
                }
            }
        } else {
            System.out.println("文件不存在!");
        }
        System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);

    }

三、Java Web
1. session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。
答:
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
①存在的位置:
cookie 存在于客户端,临时文件夹中
session:存在于服务器的内存中,一个session域对象为一个用户浏览器服务
②安全性
cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放
session存放于服务器的内存中,所以安全性好
③网络传输量
cookie会传递消息给服务器
session本身存放于服务器,不会有传送流量
④生命周期(以20分钟为例)
(1)cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束,
(2)session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁
但是,如果在20分钟内(如在第19分钟时)访问过session,那么,将重新计算session的生命周期
(3)关机会造成session生命周期的结束,但是对cookie没有影响
⑤访问范围
cookie为一个用户浏览器独享
session为多个用户浏览器共享
如果客户端不支持cookie,可以采用url重写技术或者表单隐藏技术实现追踪用户状态。
2. servlet的一些相关问题
答:
servlet执行流程
客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相应的servlet,并将request\response对象传递给servlet,servlet根据request就可以知道是谁发出的请求、请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。
3. webservice相关问题
4. jdbc连接,forname方式的步骤,怎么声明使用一个事务。举例并具体代码
答:

public class DBHelper {  
    public static final String DBDRIVER = "com.mysql.jdbc.Driver";  
    public static final String DBURL = "jdbc:mysql://localhost:3306/test";  
    public static final String DBUSER = "root";  
    public static final String DBPASS = "1111";  

    public static Connection getConnection(){  
        Connection conn = null;  
        try {  
            Class.forName(DBDRIVER);  
            conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return conn;  
    }   

    public static void save(){  
        Connection con = getConnection();  
        String sql = "insert into Info values(?, ?, ?)";  
        PreparedStatement psmt = null;  
        try {  
            psmt = con.prepareStatement(sql);  
            psmt.setString(1, "123");  
            psmt.setString(2, "12");  
            psmt.setInt(3, 3);  
            int count = psmt.executeUpdate();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }finally{  
            if(psmt != null){  
                try {  
                    psmt.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
            if(con != null){  
                try {  
                    con.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  
   }
  1. 无框架下配置web.xml的主要配置内容
    答:
    主要由listener->filter->servlet构成
    参考web.xml配置
  2. jsp和servlet的区别
    答:
    jsp本质上就是servlet;但两者创建方式不同,servlet由java代码构成,主要控制流程和事务处理;jsp由html和jsp标签组成,主要生成动态网页。

猜你喜欢

转载自blog.csdn.net/li1987by/article/details/79812781