Complete Works of Java Interview Questions(8)

Complete Works of Java Interview Questions(8)

Baiyu IT haha

71. How to list all files in a directory with Java code?

Answer:
If you only need to list the files in the current folder, the code is as follows:


import java.io.File;
class Test12 {
    public static void main(String[] args) {
        File f = new File("/Users/Hao/Downloads");
        for(File temp : f.listFiles()) {
            if(temp.isFile()) {
                System.out.println(temp.getName());
            }
        }
    }
}

If you need to continue to expand the folder, the code is as follows:


import java.io.File;
class Test12 {
    public static void main(String[] args) {
        showDirectory(new File("/Users/Hao/Downloads"));
    }
    public static void showDirectory(File f) {
        _walkDirectory(f, 0);
    }
    private static void _walkDirectory(File f, int level) {
        if(f.isDirectory()) {
            for(File temp : f.listFiles()) {
                _walkDirectory(temp, level + 1);
            }
        }
        else {
            for(int i = 0; i < level - 1; i++) {
                System.out.print("\t");
            }
            System.out.println(f.getName());
        }
    }
}

You can use the NIO.2 API to do the same thing in Java 7. The code is as follows:


class ShowFileTest {
    public static void main(String[] args) throws IOException {
        Path initPath = Paths.get("/Users/Hao/Downloads");
        Files.walkFileTree(initPath, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
                    throws IOException {
                System.out.println(file.getFileName().toString());
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

72. Use Java socket programming to implement a multi-threaded echo server.

answer:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
    private static final int ECHO_SERVER_PORT = 6789;
    public static void main(String[] args) {        
        try(ServerSocket server = new ServerSocket(ECHO_SERVER_PORT)) {
            System.out.println("服务器已经启动...");
            while(true) {
                Socket client = server.accept();
                new Thread(new ClientHandler(client)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static class ClientHandler implements Runnable {
        private Socket client;
        public ClientHandler(Socket client) {
            this.client = client;
        }
        @Override
        public void run() {
            try(BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    PrintWriter pw = new PrintWriter(client.getOutputStream())) {
                String msg = br.readLine();
                System.out.println("收到" + client.getInetAddress() + "发送的: " + msg);
                pw.println(msg);
                pw.flush();
            } catch(Exception ex) {
                ex.printStackTrace();
            } finally {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Note: The above code uses Java 7's TWR syntax. Since many external resource classes indirectly implement the AutoCloseable interface (single method callback interface), you can use TWR syntax to automatically call external resources through callbacks at the end of the try. The close() method of the class avoids writing lengthy finally code blocks. In addition, the above code uses a static internal class to implement the thread function. Using multithreading can avoid the interruption caused by a user's I/O operation from affecting other users' access to the server. Simply put, a user's input operation will not cause Blocking of other users. Of course, the above code uses thread pool to get better performance, because the overhead caused by frequent creation and destruction of threads can not be ignored.

The following is a piece of echo client test code:


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class EchoClient {
    public static void main(String[] args) throws Exception {
        Socket client = new Socket("localhost", 6789);
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入内容: ");
        String msg = sc.nextLine();
        sc.close();
        PrintWriter pw = new PrintWriter(client.getOutputStream());
        pw.println(msg);
        pw.flush();
        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        System.out.println(br.readLine());
        client.close();
    }
}

If you want to use NIO's multiplexed socket to implement a server, the code is as follows. Although the operation of NIO brings better performance, some operations are relatively low-level, which is still a bit difficult for beginners to understand.


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class EchoServerNIO {
    private static final int ECHO_SERVER_PORT = 6789;
    private static final int ECHO_SERVER_TIMEOUT = 5000;
    private static final int BUFFER_SIZE = 1024;
    private static ServerSocketChannel serverChannel = null;
    private static Selector selector = null;    // 多路复用选择器
    private static ByteBuffer buffer = null;    // 缓冲区
    public static void main(String[] args) {
        init();
        listen();
    }
    private static void init() {
        try {
            serverChannel = ServerSocketChannel.open();
            buffer = ByteBuffer.allocate(BUFFER_SIZE);
            serverChannel.socket().bind(new InetSocketAddress(ECHO_SERVER_PORT));
            serverChannel.configureBlocking(false);
            selector = Selector.open();
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private static void listen() {
        while (true) {
            try {
                if (selector.select(ECHO_SERVER_TIMEOUT) != 0) {
                    Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                    while (it.hasNext()) {
                        SelectionKey key = it.next();
                        it.remove();
                        handleKey(key);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private static void handleKey(SelectionKey key) throws IOException {
        SocketChannel channel = null;
        try {
            if (key.isAcceptable()) {
                ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                channel = serverChannel.accept();
                channel.configureBlocking(false);
                channel.register(selector, SelectionKey.OP_READ);
            } else if (key.isReadable()) {
                channel = (SocketChannel) key.channel();
                buffer.clear();
                if (channel.read(buffer) > 0) {
                    buffer.flip();
                    CharBuffer charBuffer = CharsetHelper.decode(buffer);
                    String msg = charBuffer.toString();
                    System.out.println("收到" + channel.getRemoteAddress() + "的消息:" + msg);
                    channel.write(CharsetHelper.encode(CharBuffer.wrap(msg)));
                } else {
                    channel.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (channel != null) {
                channel.close();
            }
        }
    }
}

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public final class CharsetHelper {
    private static final String UTF_8 = "UTF-8";
    private static CharsetEncoder encoder = Charset.forName(UTF_8).newEncoder();
    private static CharsetDecoder decoder = Charset.forName(UTF_8).newDecoder();    private CharsetHelper() {
    }
    public static ByteBuffer encode(CharBuffer in) throws CharacterCodingException{
        return encoder.encode(in);
    }
    public static CharBuffer decode(ByteBuffer in) throws CharacterCodingException{
        return decoder.decode(in);
    }
}

73. How many forms of XML document definition? What is the essential difference between them? What are the ways to parse XML documents?

Answer: There are two forms of XML document definition: DTD and Schema, both of which are constraints on XML grammar. The essential difference is that Schema itself is also an XML file, which can be parsed by an XML parser and can define data carried by XML. Type and restraint ability is more powerful than DTD. The analysis of XML mainly includes DOM (Document Object Model), SAX (Simple API for XML) and StAX (a new way of parsing XML introduced in Java 6, Streaming API for XML), where DOM processes large files When its performance drops very severely, this problem is caused by the memory occupied by the DOM tree structure, and the DOM parsing method must load the entire document into the memory before parsing the file, which is suitable for random access to XML (typical space Strategy in exchange for time); SAX is an event-driven XML parsing method, which reads XML files sequentially without loading the entire file all at once. When it encounters things like the beginning of the file, the end of the document, or the beginning of the tag and the end of the tag, it will trigger an event. The user processes the XML file through the event callback code, which is suitable for sequential access to XML; as the name implies, StAX focuses on the stream In fact, the essential difference between StAX and other parsing methods is that the application can process XML as an event stream. The idea of ​​treating XML as a set of events is not new (SAX does this), but the difference is that StAX allows the application code to pull these events out one by one, instead of providing them from the parser when it is convenient Receive event handler.

74. Where did you use XML in your project?

Answer: There are two main functions of XML: data exchange and information configuration. When doing data exchange, XML assembles data with tags, then compresses, packs and encrypts and transmits it to the receiver through the network. After receiving, decrypting and decompressing, the relevant information is restored from the XML file for processing. XML used to be a heterogeneous system The de facto standard for data exchange, but this feature has almost been replaced by JSON (JavaScript Object Notation). Of course, many software still use XML to store configuration information. In many projects, we usually write hard code as configuration information in XML files. Many Java frameworks do this, and these frameworks have chosen dom4j. As a tool for processing XML, because Sun's official API is really not easy to use.

Supplement: Nowadays, many fashionable software (such as Sublime) have begun to write configuration files into JSON format, and we have strongly felt that another function of XML will gradually be abandoned by the industry.

75. Explain the steps of JDBC operating database.

Answer: The following code uses the local Oracle database as an example to demonstrate the steps of JDBC operating the database.

  • 加载驱动。
    Class.forName("oracle.jdbc.driver.OracleDriver");
  • 创建连接。
    Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");
  • 创建语句。
    PreparedStatement ps = con.prepareStatement("select * from emp where sal between ? and ?");
    ps.setInt(1, 1000);
    ps.setInt(2, 3000);
  • Execute the statement.
    ResultSet rs = ps.executeQuery();
  • 处理结果。
    while(rs.next()) {
    System.out.println(rs.getInt("empno") + " - " + rs.getString("ename"));
    }
  • Close the resource.

    finally {
            if(con != null) {
                        try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

Tip: The order of closing external resources should be the opposite of the order of opening, that is to say, close the ResultSet first, then close the Statement, and close the Connection. The above code only closes the Connection. Although in general, when the connection is closed, the statements created on the connection and the opened cursor will also be closed, but there is no guarantee that this will always be the case, so they should be closed in the order just mentioned. In addition, the first step to load the driver can be omitted in JDBC 4.0 (automatically load the driver from the classpath), but we recommend keeping it.

76. What is the difference between Statement and PreparedStatement? Which is better?

Answer: Compared with Statement, ①PreparedStatement interface represents prepared statements. Its main advantage is that it can reduce SQL compilation errors and increase SQL security (reducing the possibility of SQL injection ***); ②The SQL statement in PreparedStatement is Can take parameters, avoiding the trouble and insecurity of splicing SQL statements with string connections; ③When batch processing SQL or frequently executing the same query, PreparedStatement has obvious performance advantages, because the database can optimize the compilation The SQL statement is cached, and the next time the statement of the same structure is executed, it will be quick (without compiling and generating the execution plan again).

Supplement: In order to provide calls to stored procedures, the JDBC API also provides the CallableStatement interface. Stored procedure (Stored Procedure) is a set of SQL statements in the database to complete a specific function, compiled and stored in the database, the user specifies the name of the stored procedure and gives parameters (if the stored procedure has parameters). Execute it. Although calling stored procedures will gain many benefits in network overhead, security, and performance, there will be a lot of trouble if the underlying database is migrated, because there are many differences in the writing of stored procedures for each database.

77. How to improve the performance of reading data when using JDBC to operate the database? How to improve the performance of updating data?

Answer: To improve the performance of reading data, you can specify the number of records to be fetched each time through the setFetchSize() method of the ResultSet object (a typical space-for-time strategy); to improve the performance of updating data, you can use PreparedStatement The statement builds a batch, and several SQL statements are executed in a batch.

78. What is the role of the connection pool during database programming?

Answer: Because there is a lot of overhead in creating and releasing connections (especially when the database server is not local, TCP three-way handshake is required to establish a connection each time, and TCP four-way handshake is required to release the connection. The overhead caused cannot be ignored. ), in order to improve the performance of the system to access the database, you can create a number of connections in advance and put them in the connection pool, and get them directly from the connection pool when needed, and return the connection pool at the end of use without closing the connection, thus avoiding frequent creation and release of connections. This is a typical strategy of exchanging space for time (a waste of space for storing connections, but saving time for creating and releasing connections). Pooling technology is very common in Java development, and the principle of creating a thread pool when using threads is the same. Java-based open source database connection pools mainly include: C3P0, Proxool, DBCP, BoneCP, Druid, etc.

79. What is DAO mode?

Answer: DAO (Data Access Object), as its name implies, is an object that provides an abstract interface for a database or other persistence mechanism. It provides various data access operations without exposing the implementation details of the underlying persistence solution. In actual development, all access operations to the data source should be abstracted and encapsulated in a public API. In programming language, it is to establish an interface, which defines all the transaction methods that will be used in this application. In this application, use this interface when you need to interact with the data source, and write a separate class to implement this interface, which logically corresponds to a specific data store. DAO mode actually contains two modes, one is Data Accessor (data accessor), the other is Data Object (data object), the former must solve the problem of how to access data, while the latter must solve the problem of how to encapsulate data with objects.

Guess you like

Origin blog.51cto.com/15061944/2593702