java面试

java面试Socket相关

2018-04-09  本文已影响0人  pr0metheus

面试题目一:编写一个网络应用程序,有客户端与服务器端,客户端向服务器发送一个字符串,服务器收到该字符串后将其打印到命令行上,然后向客户端返回该字符串的长度,最后,客户端输出服务器端返回的该字符串的长度

答案:具体代码如下

//服务器端代码
public class Server {

    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(65000);
        while (true) {
            Socket socket = ss.accept();
            new MyThread(socket).start();
        }
    }
}

class MyThread extends Thread {
    private Socket socket;

    public MyThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            OutputStream os = socket.getOutputStream();
            InputStream is = socket.getInputStream();
            int ch = 0; 
            byte[] buff = new byte[1024];
            ch = is.read(buff);
            String content = new String(buff, 0, ch);
            System.out.println(content);
            os.write(String.valueOf(content.length()).getBytes());
            
            is.close();
            os.close();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//客户端代码
public class Client {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 65000);
        OutputStream os = socket.getOutputStream();
        InputStream is = socket.getInputStream();
        os.write(new String("hello world").getBytes());
        int ch = 0; 
        byte[] buff = new byte[1024];
        ch = is.read(buff);
        String content = new String(buff, 0, ch);
        System.out.println(content);
        is.close();
        os.close();
        socket.close();
    }
}

面试题目二:请用UDP通信方式完成上述问题,并说说UDP与TCP的区别

答案:具体代码见如下所示

//服务端代码
public class UDPServer {

    public static void main(String[] args) throws Exception {
        // 服务端接受客户端发送的数据报
        DatagramSocket socket = new DatagramSocket(65001); //监听的端口号
        byte[] buff = new byte[100]; //存储从客户端接受到的内容
        DatagramPacket pocket = new DatagramPacket(buff, buff.length);
        //接受客户端发送过来的内容,并将内容封装进DatagramPacket对象中
        socket.receive(pocket); 

        byte[] data = pocket.getData(); //从DatagramPacket对象中获取到真正存储的数据
        //将数据从二进制转换成字符串形式
        String content = new String(data, 0, pocket.getLength()); 
        System.out.println(content); 
        //将要发送给客户端的数据转换成二进制
        byte[] sendedContent = String.valueOf(content.length()).getBytes(); 
        // 服务端给客户端发送数据报
        //从DatagramPacket对象中获取到数据的来源地址与端口号
        DatagramPacket packetToClient = new DatagramPacket(sendedContent,
                sendedContent.length, pocket.getAddress(), pocket.getPort()); 
        socket.send(packetToClient); //发送数据给客户端
    }
}
//客户端的代码
public class UDPClient {

    public static void main(String[] args) throws Exception {
        // 客户端发数据报给服务端
        DatagramSocket socket = new DatagramSocket();
        // 要发送给服务端的数据
        byte[] buf = "Hello World".getBytes();
        // 将IP地址封装成InetAddress对象
        InetAddress address = InetAddress.getByName("127.0.0.1");
        // 将要发送给服务端的数据封装成DatagramPacket对象 需要填写上ip地址与端口号
        DatagramPacket packet = new DatagramPacket(buf, buf.length, address,
                65001);
        // 发送数据给服务端
        socket.send(packet);

        // 客户端接受服务端发送过来的数据报
        byte[] data = new byte[100];
        // 创建DtagramPacket对象用来存储服务端发送过来的数据
        DatagramPacket receivedPacket = new DatagramPacket(data, data.length);
        // 将接受到的数据存储到DatagramPacket对象中
        socket.receive(receivedPacket);
        // 将服务器端发送过来的数据取出来并打印到控制台
        String content = new String(receivedPacket.getData(), 0,
                receivedPacket.getLength());
        System.out.println(content);

    }
}

UDP与TCP的区别是:UDP是用户数据报协议是无连接的,不可靠的,数据的到达时间,到达顺序,数据是否能够到达及数据到达的完整性都是无法保证的,类似于寄信,适用于视频会议等对速度要求高但对数据完整性要求不严格的场景,而TCP是传输控制协议,数据的传输建立在连接之上,是可靠的,TELNET、FTP、HTTP都是建立在TCP之上的,因为有连接所以在JAVA中用输入输出流来传输数据。

用UDP编程使用到类DatagramSocket、DatagramPacket
用TCP编程使用到类ServerSocket、Socket

面试题目三:用socket编写一个服务端与客户端的聊天程序

答案:具体代码如下所示

//服务器端代码
//监听端口,每成功连接一个客户机就开启一个线程进行读写处理
public class Server {

    public static void main(String[] args) throws Exception {
        ServerSocket ss = new ServerSocket(65000);
        while (true) {
            Socket socket = ss.accept();
            new MyThread(socket).start(); //开启一个线程用于处理已连接上的socket
        }
    }
}
//开启两个线程分别用来处理socket中的输入输出流
class MyThread extends Thread {
    private Socket socket;

    public MyThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            //开启两个线程分别来处理服务端的读写
            new OutputThread(socket.getOutputStream()).start();
            new InputThread(socket.getInputStream()).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//处理socket的输出流
class OutputThread extends Thread {
    private OutputStream os;
    public OutputThread(OutputStream os) {
        this.os = os;
    }
    
    @Override
    public void run() {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        try {
            while ((line = br.readLine()) != null) {
                os.write((line).getBytes());
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//处理socket的输入流
class InputThread extends Thread {
    private InputStream is;
    public InputThread(InputStream is) {
        this.is = is;
    }
    @Override
    public void run() {
        int ch = 0; 
        byte[] buff = new byte[1024];
        try {
            while ((ch = is.read(buff)) != -1) {
                String content = new String(buff, 0, ch);
                System.out.println(content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
//客户端代码
public class Client {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 65000);
        new MyThread(socket).start(); //开启一个线程用于处理已连接上的socket
    }
}

面试题目四:Collections和Collection的区别?

答案:Collections是集合辅助类,里面提供了一系列方法来方便我们操纵集合,而Collection是List与Set的父接口

面试题目五:HashTable和HashMap区别

答案:HashTable是同步的、在单线程环境下效率低,它的键与值都不能为空。HashMap是不同步的、在单线程环境下效率高,它的键与值都可为空。

面试题目六:如下两个程序能否编译通过?并说明为什么

//代码-1
short s = 1;
s = s + 1;
//代码-2
short s = 1;
s += 1;

答案:代码-1不能够编译通过,因为执行s + 1操作的时候,低类型会自动往高类型转,所以执行完后的结果是int类型,然后int类型是无法直接赋值给short类型的,必须要进行向下类型转换才可。而代码-2可以编译通过,因为使用了+=的运算符,该运算符隐藏着强制类型转换的操作,相等于s = (short) (s + 1);

上一篇下一篇

猜你喜欢

热点阅读