1. 程式人生 > >那年我梳理的Java程式設計題

那年我梳理的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階段最具代表性的專案