那年我梳理的Java程式設計題
SE階段代表性程式設計題
1.列印九九乘法表(雙重for迴圈)
public class TestStudy { /** * 列印九九乘法表 * @param args */ public static void main(String[] args) { for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { System.out.print(i+"x"+j + "=" + i*j +" "); } System.out.println(); } } }
2.列印水仙花數
/* 程式設計實現所有三位數水仙花數的列印 */ public class TestWaterFlower{ public static void main(String[] args){ //1.列印所有的三位數 for(int i = 100; i <= 999; i++){ //2.拆分該三位數中的每個數字 123 int ia = i / 100; //獲取百位數 int ib = i % 100 / 10; //獲取十位數 int ic = i % 10; //獲取個位數 //3.判斷i代表的數值是否為水仙花數,若是則列印 if((ia*ia*ia + ib*ib*ib + ic*ic*ic) == i){ System.out.println(i); } } } }
3.陣列的增刪改查
陣列增刪不便,牽一髮而動全身
查詢方便,支援下標訪問
Arrays.sort(arr);呼叫方法進行陣列排序,底層實現方式是:快速排序
程式設計實現雙色球:
package cn.xdl.test; import java.util.Arrays; import java.util.Random; public class TestStudy { public static void main(String[] args) { int[] arr = new int[6]; //呼叫隨機函式 Random random = new Random(); for (int i = 0; i < 6; i++) { //呼叫隨機函式生成1~33之間的隨機數並對陣列進行賦值 arr[i] = random.nextInt(33)+1; //針對每次生成的隨機號碼進行去重操作 for (int j = i-1 ; j >=0 ;j--) { //如果有相等,i--重新執行生成操作 if(arr[i] == arr[j]){ i--; break; } } } Arrays.sort(arr);//排序 int red = random.nextInt(16)+1; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]+" "); } System.out.println(red); } }
程式設計實現五子棋(控制檯版):二維陣列
package cn.yimu.goband;
/*
程式設計實現控制檯版的五子棋遊戲,支援兩人對戰
*/
import java.util.Scanner;
public class Goband {
//自定義二維陣列來描述棋盤,預設初始值為0
int[][] chessBoard = new int[16][16];
//自定義成員方法來繪製棋盤
void paint(){
//1.先繪製棋盤中第一行的座標資訊,也就是列座標資訊
for(int i = 0; i < 17; i++){
if(i == 0){
System.out.print(" ");
}
else{
//按照十六進位制的格式列印i-1的數值
System.out.printf("%x ", i-1);
}
}
System.out.println();
//2.繪製棋盤中除了第一行之外的其他部分以及行座標資訊
for(int i = 0; i < 16; i++){
//用於列印行座標資訊
System.out.printf("%x ", i);
for(int j = 0; j < 16; j++){
//剛開始棋盤中的所有內容都是+,因此直接列印
if(chessBoard[i][j] == 0){
System.out.print("+ ");
}
else if(chessBoard[i][j] == 1){
System.out.print("● ");
}
else{
System.out.print("○ ");
}
}
//列印完畢一行的所有內容之後進行換行
System.out.println();
}
}
//自定義成員方法來提示黑方和白方分別下棋
void play(){
//定義標誌位來進行黑方和白方的切換,true代表黑方,false代表白方
boolean flag = true;
//不斷地分別提示黑方和白方下棋
while(true){
System.out.println("請" + (flag ? "黑方": "白方") + "輸入落子座標(x y):");
Scanner sc = new Scanner(System.in);
int ix = sc.nextInt();
int iy = sc.nextInt();
//根據使用者輸入的座標來調整棋盤中的圖案,策略為改變陣列的元素值
if(flag){
//當黑方落子時就將陣列中對應元素值改為1
chessBoard[ix][iy] = 1;
}else{
//當白方落子時就將陣列中對應元素改為2
chessBoard[ix][iy] = 2;
}
//重新繪製圖案
paint();
//判斷當前方是否勝利,若勝利就立刻結束遊戲
if(judge(ix, iy)){
System.out.println("恭喜" + (flag ? "黑方": "白方") + "勝利了!");
break;
}
//此時切換下棋方
flag = !flag;
}
}
//自定義成員方法來判斷使用者是否獲勝,獲勝的規則是:任意相同顏色的5個棋子連成一線
boolean judge(int ix, int iy){
//1.判斷豎向是否連成一線,則需要以該點為中心向上四個點向下四個點
//宣告變數來統計豎向相同顏色棋子的個數,先統計向上同色棋子的個數
int count = 1;
for(int i = ix-1; i >= 0 && i >= ix-4; i--){
//若當前點代表的棋子與上述某個點代表的棋子不一樣,則向上統計結束
if(chessBoard[ix][iy] != chessBoard[i][iy]){
break;
}
count++;
}
System.out.println("count1 = " + count);
//再統計向下顏色相同的個數
for(int i = ix+1; i <= 15 && i <= ix+4; i++){
if(chessBoard[ix][iy] != chessBoard[i][iy]){
break;
}
count++;
}
System.out.println("count2 = " + count);
//... ...
return count >= 5;
//當所有可能勝利的情況都排除了,那麼肯定是失敗了
}
}
啟動類:
public class TestGoband {
public static void main(String[] args) {
//1.宣告一個GoBand型別的引用指向該類的物件
Goband gb = new Goband();
//2.呼叫成員方法來繪製棋盤
gb.paint();
//3.呼叫成員方法來進行下棋
gb.play();
}
}
4.遞迴方法的呼叫
所謂遞迴就是自己呼叫自己的方法:
遞迴有可能會大幅簡化程式碼的編寫。遞迴要考慮效能問題,有些時候可以使用迴圈而不是遞迴。
遞迴的使用原則:
1 必須有退出條件。
2 必須使問題變簡單,而不是複雜化。
遞迴方式實現階乘:
public class TestDG {
/**
* 自定義演算法實現階乘
* 階乘:1*2*3*4...*n
* @param n
* @return
*/
int factorial(int n){
if(n == 1){
return 1;
}
return n*factorial(n-1);
}
public static void main(String[] args) {
TestDG dg = new TestDG();
System.out.println(dg.factorial(4));
}
}
費時數列的遞迴實現
public class TestDG {
/**
* 自定義遞迴實現費式數列
* 費式數列:也叫斐波那契數列:即從1開始,後一個數等於前兩個數之後1、1、2、3、5、8、13、21...
* @return
*/
int sequence(int n){
if(n == 1 || n == 2){
return 1;
}
return sequence(n-1)+sequence(n-2);
}
public static void main(String[] args) {
TestDG dg = new TestDG();
System.out.println(dg.sequence(45));
}
}
5.單例設計模式(餓漢式,懶漢式)
餓漢式:
public class Singleton(){
//1 私有化構造方法
private Singleton(){}
//2 提供一個本類型別的引用指向本類的物件
private static Singleton sin = new Singleton();
//3 提供一個公用的方法將sin的數值返回出去
public static Singleton getInstance(){
return sin;
}
}
懶漢式:
public calss Singleton(){
private Singleton(){};
private static Singleton sin = null;
public static Singleton getInstance(){
if(sin == null){
sin = new Singleton();
}
return sin;
}
}
6.匿名內部類
Thread th = new Thread(){
編寫程式碼;
};
7.自定義異常類
自定義異常類:繼承自Exception
public class AgeException extends Exception{
編寫程式碼;
}
8.遞迴實現多層檔案讀取檔名
import java.io.File;
public class PrintList {
/**
* 自定義方法列印引數指定目錄及其子目錄中的檔案
* @param file
*/
public static void print(File file){
// 判斷是否是普通檔案
if(file.isFile()){
System.out.println(file.getName());
}else if(file.isDirectory()){
//獲取目錄中的所用內容
File[] fArr = file.listFiles();
//使用遞迴,列印所有
for (File f: fArr) {
print(f);
}
}
}
public static void main(String[] args) {
File file = new File("目錄或者檔名");
PrintList.print(file);
}
}
9.使用byte[] 實現檔案的拷貝
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileCopy {
public static void main(String[] args) {
try {
//檔案流物件,關聯需要拷貝檔案
FileInputStream fis = new FileInputStream("輸出檔名");
FileOutputStream fos = new FileOutputStream("輸入檔名");
//準備一個合理的快取區,每次只需要將快取區寫滿再寫入
byte[] brr = new byte[1024*8];
int res =0;
while((res = fis.read(brr)) != -1){
fos.write(brr,0,res);
}
fis.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
10.多執行緒的實現方式(擴充套件)
方式一:繼承Thread類
/**
* 1 繼承Thread類
* 2 重寫run方法
* 3 呼叫start()開啟執行緒
* @author liangmu
*/
public class WayThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 26; i++) {
System.out.println(“執行緒一:” + i);
}
}
public static void main(String[] args) {
Thread th = new WayThread();
th.start();//啟動一個執行緒的方法
for (int i = 0; i < 21; i++) {
System.out.println(“main執行緒:”+ i);
}
}
}
方式二:實現Runnable介面
/**
* 方式二
* 1 實現Runnable介面
* 2 重寫run方法
* 3 開啟執行緒
* @author liangmu
*
*/
public class WayThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("子執行緒:" + i);
}
}
public static void main(String[] args) {
Runnable ra = new WayThread();
Thread th = new Thread(ra);
th.start();
for (int i = 0; i < 100; i++) {
System.out.println("主執行緒方法:" + i);
}
}
}
方式三:匿名內部類
/**
* 方式三:
* 使用匿名內部類的方式呼叫
* @author liangmu
*
*/
public class WayThread{
public static void main(String[] args) {
Thread th = new Thread(){
public void run(){
for (int i = 0; i < 30; i++) {
System.out.println("執行緒一" + i);
}
}
};
th.start();
new Thread(){
public void run(){
for (int i = 0; i < 30; i++) {
System.out.println("執行緒二" + i);
}
}
}.start();
}
}
11.基於TCP協議的網路程式設計(UDP協議 擴充套件)
客戶端:
public class TestClient {
public static void main(String[] args) {
try{
//1.建立Socket型別的物件,並提供伺服器的IP地址和埠號
Socket s = new Socket("localhost", 8888);
//2.使用輸入輸出流進行通訊
PrintStream ps = new PrintStream(s.getOutputStream());
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
Scanner sc = new Scanner(System.in);
while(true){
//String msg = "在嗎?";
System.out.println("請輸入要傳送的內容:");
String msg = sc.nextLine();
ps.println(msg);
System.out.println("傳送資料成功!");
//判斷客戶端給伺服器傳送的內容是否為"bye"
if("bye".equalsIgnoreCase(msg)){
System.out.println("再見吧!");
break;
}
//接收伺服器回發的訊息
String str = br.readLine();
System.out.println("伺服器發來的資料是:" + str);
}
//3.關閉Socket並釋放有關的資源
br.close();
ps.close();
s.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
服務端:
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
try {
//建立ServerSocket型別的物件,並提供埠號
ServerSocket ss = new ServerSocket(8888);
while(true){
System.out.println("等待客戶端連線請求...");
Socket s = ss.accept();
System.out.println(s.getInetAddress()+"連線成功");
ServerThread thread = new ServerThread(s);
Thread th = new Thread(thread);
th.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
執行緒:
public class ServerThread implements Runnable{
private Socket s;
public ServerThread(Socket s){
this.s = s;
}
@Override
public void run(){
try{
//3.使用輸入輸出流進行通訊
BufferedReader br = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintStream ps = new PrintStream(s.getOutputStream());
while(true){
String str = br.readLine();
System.out.println("客戶端" + s.getInetAddress()
+ "發來的資料是:" + str);
//判斷客戶端發來的資料是否為"bye",若是則結束通訊
if("bye".equalsIgnoreCase(str)){
System.out.println("話不投機半句多!客戶端"
+ s.getInetAddress() + "已下線!");
break;
}
//實現伺服器向客戶端回發訊息
ps.println("I received!");
System.out.println("伺服器傳送資料成功!");
}
//4.關閉Socket並釋放有關的資源
ps.close();
br.close();
s.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
12.冒泡演算法(快速演算法 擴充套件)
public class TestSort(){
public static void bubble(int[] arr){
//1.使用外層for迴圈來控制比較的輪數
for(int i=1;i<arr.length;i++){
boolean flag = true;//打標記
//2.使用內層for迴圈來控制每一輪中比較的次數,也就是j的取值範圍
for(int j=0;j<arr.length-i;j++){
//3.若左邊的元素比右邊的元素大,則交換兩個元素的位置
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = false;
}
}
if(flag) break;
}
}
public static void main(String[] args){
int[] arr = {12,32,25,2,6,86,63,21,15,36};
TestSort.bubble(arr);
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
13.工廠模式 抽象工廠模式(23種設計模式 擴充套件)
設計模式: 設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。設計模式本質上就是一種固定的套路,使用在固定的場合中。
分類:
建立型模式 - 工廠方法模式、抽象工廠模式、單例設計模式。
結構型模式 - 裝飾器模式、代理模式。
行為型模式 - 模板設計模式、觀察者模式。
1、工廠方法模式(Factory Method):
普通工廠模式:(郵件和簡訊的例子)
介面:
public interface Sender{
public void send();
}
介面實現類:
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("郵件傳送");
}
}
public class SmsSender implements Sender {
@Override
public void send() {
System.out.println("資訊傳送");
}
}
工廠類:
public class SendFactory {
//工廠方法
public Sender produce(String type){
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("請輸入正確的型別!");
return null;
}
}
}
工廠測試類:
public class TestFactory {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Sender sms = sendFactory.produce("sms");
sms.send();
}
}
多個工廠方法模式:
即在工廠類中新增多個工廠方式
靜態工廠方法模式:
即將工廠類中的方法設定為靜態的加static,不需要建立例項,可直接呼叫
抽象工廠模式
工廠方法模式有一個問題就是,類的建立依賴工廠類,也就是說,如果想要拓展程式,必須對工廠類進行修改,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,如何解決?就用到抽象工廠模式,建立多個工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的程式碼
![](https://i.imgur.com/DnyYVD1.png)
介面:
實現類:
工廠類實現介面方法:
測試類:
14.學生資訊管理系統
c/s架構編寫,SE階段最具代表性的專案