第一題
題目描述
C語?標準庫函式int atoi (const char *)和long int atol ( const char *),可以分別將給定的字串轉 換為整數(int)和?整數(long),具體轉換規則如下:丟棄前?的空?字符(空格、水平以及垂 直制表、換頁、回車、換行,其相應的ASCII碼值附后),直到第?個非空白字符為止;從該字符開 始,接收可選的+或-號,后跟任意的?進制數字字符并將其解釋為數字值;字串在構成整數的數 字字符之后可以包含額外的其它字符,?旦遇到這樣的字符,轉換?即停?;如果字串的第?個
非空?字符并不是?個有效的數字字符,或者它為慷訓僅僅包含空?字符,那么不會執?轉換,僅僅回傳0,以下是對外提供這兩個功能的NumUtil類,請根據該轉換規則以及中的注釋:(1)如果類 或有關?法的宣告中存在錯誤,說明如何修改,main()方法體中,除了編號部分,不允許被修改,
(2)完成相關?法,要求不得使?標準Java?身的有關決議數值的類及其?法;(3)在main()?法中,根據下表中所給的測驗?例執?單元測驗(并?實際產品開發中的測驗?式),
java代碼實作
public class NumUtil {
//判斷是否是空字符
static private boolean isWhitespace(char c) {
/*(1)*/
switch(c) {
case ' ':
case '\t':
case '\f':
case '\r':
case '\n':
case '\u000b':
return true;
default:
return false;
}
}
//找到第一個非空字符的位置
static private int skipWhitespace(String source) {
//(2)
int i = 0;
while(i < source.length()) {
if(isWhitespace(source.charAt(i)))
i++;
else
break;
}
return i;
}
//字串轉化成長整數
public static long atol(String source) {
int sign = 1, i; // sign of the result long integer, i current position in source
long res = 0; // the final result long integer
// skip the whitespaces (3)
i = skipWhitespace(source);
if(i == source.length()) return res;//這里應該判斷一下非空字符下標是否越界
// process the sign symbol (4)
switch(source.charAt(i)) {
case '+':
i++;
break;
case '-':
sign = -1;
i++;
break;
default:
break;
}
// process any digit characters
//(5)
for(; i < source.length(); i++) {
char c = source.charAt(i);
if(c >= '0' && c <= '9')
res = 10 * res + c - '0';
else
break;
}
// return the converted result long integer return (6)
return res*sign;
}
//字串轉整數,直接將long強值轉化即可
public static int atoi(String source) {
//(7)
return (int)atol(source);
}
/**
* Determine if the given test had passed and output the result
* according to the following format:
* <pre>
* Test case: n -> passed|failed
* where n is the number of the test case.
* </pre>
* @param test the number of the test case.
* @param factual the converted integer.
* @param expected the expected integer.
*/
//根據上面注釋給出的格式輸出測驗結果
public static void check(int test, int factual, int expected) {
//(8)
if(factual == expected) {
System.out.println("Test case: "+test+ " -> passed");
}
else {
System.out.println("Test case: "+test+ " -> failed");
}
}
// Just for test!
public static void main(String[] args) {
// test case 1
//main函式中不能直接呼叫非靜態函式,應該創建物件或者轉成靜態函式
String source = "";
int res = atoi(source);
check(1, res, 0);
// test case 2
//也就是一個測驗示例
source = " \t\f\r\n\u000b12345a8";//(9)
res = atoi(source);
check(2, res, 12345);
// test case 3
// test case 4
// test case 5
}
}

第二題
題目描述
在Web應?程式中,為了提?系統的回應性,可以將?戶請求的結果快取在記憶體中,當?戶后續請求相同的資源時,不必從資料存盤中提取,?可以直接從記憶體中提供;當某個?戶對相同的資源 進?更新時,除了更新資料存盤,還應該更新快取,但統?資源識別符號(URI-Uniform ResourceIdentifier)不能更改;當請求洗掉某個資源被時,除了從資料存盤中將其洗掉之外,如果該資源已
經被快取,還應將其從快取中洗掉;為了降低系統記憶體的消耗,每隔?定的時間,應該清除快取中 超過?定期限的項?,快取的項?中包括請求的URI(字串形式)、應答體(字串形式)以及進?快取的時間(UNIX紀元即?從1970年1?1?0時0分0秒以來的毫秒數),為了簡單起?,不考慮 多服務器的分布式快取?僅僅考慮單臺服務器,但需要考慮多執行緒同步問題,以下表示HTTP應答緩 存的類HttpCache在整個JVM中只能有?個實體,要求采?惰性(lazy)?式實體化,并且在多執行緒 環境下,對該類的實體化不得采?同步鎖,所需要的有關類的?法在后續的表中給出,請撰寫以下 代碼?架中編號為(1)、(2)等部分的代碼(答題時標注相應的序號)并說明HttpCache在多執行緒環境 下哪些些?法需要同步以及在當前條件下如何同步,測驗資料在后?的表格中給出,
java代碼實作
CacheItem.java
package com.njfu.cache;
public class CacheItem {
private String uri; //統一資源識別符號
private long since;//進入快取時間
private String body;//應答體
// constructor (1)
public CacheItem(String uri, String body) {
this.uri = uri;
this.body = body;
//獲取當前系統時間,單位為毫秒
this.since = System.currentTimeMillis();
}
// accessor for uri (2)
public void setUri(String uri) {
this.uri = uri;
}
public String getUri() {
return uri;
}
// accessor for since (3)
public void setSince(long since) {
this.since = since;
}
public long getSince() {
return since;
}
// accessor for body (4)
public void setBody(String body) {
this.body = body;
}
public String getBody() {
return body;
}
// When call System.out.println(aCacheItem), output “URI: uri, Since: since, Body: body” (5)
//直接字串拼接即可
public String toString() {
return "URI: "+uri+", Since: "+since+", Body: "+body;
}
}
CacheItem.java
package com.njfu.cache;
import java.util.HashMap;
import java.util.Iterator; // for Java 8-
import java.util.Map;
import java.util.Set; // Optional
//Don’t inherit from HahMap etc.
public class HttpCache {
//Cache all the HTTP responses
private Map<String, CacheItem> cache;
//7, 8, 9就是為了惰性單例
//Make the globall instance of the HTTP response cache (7)
private static class CacheMaker {
private static final HttpCache instance = new HttpCache();
}
//constructor (8)私有的構造方法,禁止直接實體化
private HttpCache() {
this.cache = new HashMap<>();
}
/**
* Retrieve the globally unique instance of the HTTP response cache.
* @return the globally unique instance of the HTTP response cache.
*/
//通過方法創建實體
public static HttpCache getInstance() {
//(9)
return CacheMaker.instance;
}
/**
* Cache the HTTP response to the given resource URI.
* @param uri the URI of the requested resource.
* @param body the HTTP response body for the requested resource.
* @return true, if the cache item for the given URI has already
* existed, it was just updated; false, this is a new resource
* request.
*/
public synchronized boolean cache(String uri, String body) {
//(10)
//利用哈希表判斷cache中是否存在uri,如果存在則進行更新,回傳true
//不存在則插入當前item,回傳false
CacheItem item = this.cache.get(uri);
if(item == null) {
this.cache.put(uri, new CacheItem(uri, body));
return false;
}
item.setBody(body);
item.setSince(System.currentTimeMillis());
return true;
}
/**
* Try to retrieve the cached response body by the given request URI.
* @param uri the request URI whose response body would be retrieved.
* @return the response body corresponding to the given request
* URI or null if the cache does not contain it.
*/
public synchronized String get(String uri) {
//(11)
//直接呼叫hashmap的get函式,不慷訓傳相對應的應答體,否則直接回傳空
CacheItem item = this.cache.get(uri);
return item == null ? null : item.getBody();
}
/**
* Remove the cached HTTP response by the given resource URI.
* @param uri the URI of the resource to deleted.
* @return true, if the cache do contain the HTTP response for
* the given resource URI and it was deleted; false, otherwise.
*/
public synchronized boolean delete(String uri) {
//呼叫hashmap中的方法remove洗掉統一資源識別符號為uri的實體
//(12)
Object o = cache.remove(uri);
return !(o == null);
}
/**
* Delete all the cached HTTP responses earlier than the given
* threshold.
* @param delta the period in milliseconds that determine all
* the responses ahead of the current time delta milliseconds
* would be deleted.
*/
public synchronized void purge(long delta) {
long now = System.currentTimeMillis();//獲取當前時間
//(13) //包括Java 8前后不同的實作
// Java 8+
//如果存在一個資源在快取時間過長則洗掉
//entrySet方法獲取的其實就是一個型別為Map.Entery<key, value>的set容器
//而set容器其實就是一個集合,可以用遍歷整個集合或removeif+Lambda運算式洗掉里面所有符合條件物件
//java8后可以用Lambda運算式+removeif
this.cache.entrySet().removeIf(e -> e.getValue().getSince() <= now - delta);
// Java 8-
//java8之前只能迭代
/*
//創立迭代器遍歷整個set容器,找到滿足條件的即可
for(Iterator<Map.Entry<String, CacheItem> > iter = cache.entrySet().iterator(); iter.hasNext();) {
if(iter.next().getValue().getSince() <= now - delta) {
iter.remove();
}
}
*/
}
//Just for test
@Override
public String toString() {
return this.cache.toString();
}
//Just for test, multi-threads not concerned!
public static void main(String[] args) {
//In this case, ‘the HttpCache.’ part is optional
HttpCache.getInstance().cache("185080101",/*(14)*/"{no: \"185080101\", name: \"zhangsan\", gender: \"M\"}");
//一些測驗,可以不看
//HttpCache c = HttpCache.getInstance();
//System.out.println(c.delete("185080101"));
//c.cache(, "{no: \"185080101\", name: \"zhangsan\", gender: \"M\"}");
//System.out.println(c);
/* (14)*/
}
}


第三題
題目描述
以下是客戶端通過資料報同服務器單向通信的代碼框架,客戶端從控制臺上接收?戶輸?,按回?鍵后將所輸?的內容發送給服務器,當?戶輸?EOF時,客戶端退出;服務器端在本地環回接? 上接收來?客戶端的資料報并將其內容顯示到終端窗?的,請根據其中的注釋完成編號為(1)、(2)等 的代碼,
java代碼實作
DatagramServer.java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.function.Consumer;
public class DatagramServer {
// Port number
private static final int SERVER_PORT = 8888;
// Receiving bu?er size, maximum 1KB. For UDP, this is enough
private static final int BUF_SIZE = 1024;
public static void main(String args[]) throws Exception {
// Used to log the received packet to console
//Consumer一個函式式介面,代表一個接收輸入引數但是無回傳值的操作,相當于一個消費者
//::在java8之后可以用于獲取類的靜態方法,物件的成員方法等
Consumer<String> logger = System.out::println;//(1)
//DatagramPacket表示存放資料的資料報,DatagramSocket表示接受或發送資料報的套接字
// Create a datagram socket
//構造方法
//DatagramSocket(int port, InetAddress iad): 表示創建一個套接字,系結到特定的埠號及指定地址
DatagramSocket server = new DatagramSocket(SERVER_PORT, InetAddress.getLoopbackAddress());//(2)
//資料緩沖池
// Receiving bu?er for datagram packet
byte[] buf = new byte[BUF_SIZE];
// Keep running forever
for(;;) {
// Create a new packet
DatagramPacket packet = new DatagramPacket(buf, BUF_SIZE);//(3)
// Try to receive the datagram packet
//(4),接收資料
server.receive(packet);
// Use logger to write the content of the received packet to the console
//(5)
logger.accept(new String(packet.getData(), 0, packet.getLength()));
}
}
}
DatagramServer.java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//DatagramClient.java
//import omitted
public class DatagramClient {
//Server port number
private static final int SERVER_PORT = 8888;
//Client port
private static final int CLIENT_PORT = 8889;
//Size of the message bu?er
private static final int BUF_SIZE = 1024;
public static void main(String args[]) throws Exception {
//Create a datagram socket
//(6)
DatagramSocket client = new DatagramSocket(CLIENT_PORT, InetAddress.getLoopbackAddress());
//Data bu?er for datagram packet
byte[] buf = new byte[BUF_SIZE];
//Read user input from the console. When hit EOF, exist
//pos - the next position where to write the character.
for(int pos = 0, c; (c = System.in.read()) != -1/*(7)*/;) {
switch(c) {
case '\r': // Windows break;
case '\n': // Finished a line
//Send the message contained in the bu?er
//(8)
client.send(new DatagramPacket(buf, pos, InetAddress.getLoopbackAddress(), SERVER_PORT));
//Reset the bu?er
//(9)
pos = 0;
break;
default:
// Cache the current character
//assume no more than BUF_SIZE
buf[pos++] = (byte)c;
}
}
System.out.println("Goodbye!");
//Close the datagram socket (10)
client.close();
}
}
第四題
題目描述
根據以下所給定的簡單電?郵件客戶端的截圖,以及以下代碼?架中的注釋,完成編號為(1)、(2)等部分的代碼,當點擊按鈕“退出”時,終?該客戶端的運?,要求采?Lambda運算式,
java代碼
MailPanel.java
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
//MailPanel.java
//import omitted
public class MailPanel extends JPanel {
public MailPanel() {
//create main panel and set grid bag layout
/*(1)*/
//創建網格包布局
super(new GridBagLayout());
//create grid bag contraints
//GridBagConstraints是GridBagLayout的約束,即確定了組件的位置
GridBagConstraints c = new GridBagConstraints();
//row 0, column 0 -> 主題:
//(3)
//標題Label的位置為(0, 0),坐標為gridx->向右遞增,girdy向下遞增
c.gridx = 0;
c.gridy = 0;
this.add(new JLabel("主題:"), c);
//row 0, column 1 -> text field for subject, expand horizontally
//(4)
//第一個文本框的位置以及占用的大小
c.gridx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
this.add(new JTextField(), c);
//row 0, column 2 -> 收件?:
//(5)
c.gridx = 2;
c.fill = GridBagConstraints.NONE;
c.weightx = 0;//視窗改變時增量的大小,為0時不增
this.add(new JLabel("收件人:"), c);
//row 0, column 3 -> text field for recipient, expand horizontally
//(6)
c.gridx = 3;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
this.add(new JTextField(), c);
//row 1, colulmn 0 -> email content
//(7)
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 4;
c.weightx = 0.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
this.add(new JTextArea(), c);
//row 3, column 1 -> 發送
//(8)
c.gridx = 1;
c.gridy = 3;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.CENTER;
c.gridwidth = 1;
c.ipady = 0;
this.add(new JButton("發送"), c);
//row 3, column 3 -> 退出; exit with success code
//(9)
c.gridx = 3;
c.gridy = 3;
c.gridwidth = 1;
JButton bttn = new JButton("退出");
bttn.addActionListener(e -> System.exit(0));
this.add(bttn, c);
}
}
MailClient.java
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
//MailClient.java
//import omitted
public class MailClient {
public MailClient() {
//create the main frame
//(10)
JFrame frame = new JFrame("NJFU Emailer");
//terminate the JVM when the close icon was clicked
//(11)
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//create and add the mail panel
//(12)
frame.add(new MailPanel());
//set the initial size of the frame, width: 600, height: 500
//(13)
frame.setSize(600, 500);
//display the frame
//(14)
frame.setVisible(true);
}
public static void main(String[] args) {
//create the frame on the event dispatching thread instead of the
//main thread. You should use Lambada
//(15)
//時間派發執行緒運行圖形界面
SwingUtilities.invokeLater(MailClient::new);
//等價于SwingUtilities.invokeLater(() -> new MailClient());
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/1427.html
標籤:其他
