文章目录
- 从Java小白晋升到中级水平,开发者通常需要掌握以下核心技术和概念:
- 以下是一些初级到中级水平的Java编程经典练习题目,并简要解释思路:
- 1. **练习1:编写程序输出“Hello, World!”**
- 2. **练习2:定义一个整型变量,赋值为100,然后加1并输出**
- 3. **练习3:声明一个数组,存储5个整数,然后遍历并打印数组的所有元素**
- 4. **练习4:定义一个方法,接受两个整数参数,返回它们的和**
- 5. **练习5:实现一个简单的条件判断,如果用户输入的年龄大于等于18岁,则输出“成年人”,否则输出“未成年人”**
- 6. **练习6:实现一个简单的for-each循环遍历String数组并打印**
- 7. **练习7:创建一个方法,用于计算一个整数数组的平均值**
- 8. **练习8:实现二分查找算法在一个有序整数数组中查找给定值**
- 9. **练习9:实现一个简单的银行账户类,具有存款、取款和查询余额的功能**
- 10. **练习10:实现一个栈数据结构**
- 11. **练习11:实现一个队列数据结构(先进先出,FIFO)**
- 12. **练习12:实现一个基于链表的单向列表类**
- 13. **练习13:实现一个简单的计算器,支持加减乘除四则运算**
- 14. **练习14:实现斐波那契数列**
- 15. **练习15:实现一个简单的学生类,包含姓名、年龄、成绩等属性以及显示学生信息的方法**
- 16. **练习16:实现一个简易的图书管理系统**
- 17. **练习17:实现一个简单的单链表,并支持插入和删除节点**
- 18. **练习18:实现一个优先级队列(基于二叉堆)**
- 19. **练习19:实现一个简单的LRU缓存(Least Recently Used)**
- 20. **练习20:实现一个简单的数据库连接池**
- 21. **练习21:实现一个简单的文件上传功能(HTTP POST请求)**
- 22. **练习22:实现一个简单的文件下载器**
- 23. **练习23:实现一个简单的哈希表(HashMap)**
- 24. **练习24:实现一个简单的命令行版文本编辑器**
- 25. **练习25:实现一个简单的TCP聊天客户端和服务器**
- 26. **练习26:使用Java Swing创建一个简单的计时器应用程序**
- 27. **练习27:使用JavaFX创建一个简单的登录界面**
- 28. **练习28:实现一个简单的生产者消费者模型**
- 29. **练习29:实现一个简单的Future模式,异步获取结果**
- 30. **练习30:使用Java 8 Stream API对集合进行操作**
从Java小白晋升到中级水平,开发者通常需要掌握以下核心技术和概念:
-
Java语法与基础概念:
- 理解面向对象编程(OOP)原则:封装、继承、多态。
- 掌握Java基本数据类型、变量、运算符、流程控制语句(条件判断、循环、跳转)。
- 理解类和对象的概念,包括构造方法、成员变量、成员方法以及this关键字的使用。
- 学习数组、字符串和集合框架(List, Set, Map等)的使用。
-
类与对象高级特性:
- 学习抽象类和接口的区别及使用场景。
- 掌握方法重载和重写、访问权限修饰符(private, protected, public, default)。
- 理解内部类、匿名内部类、静态内部类的应用。
- 学习Java内存模型,了解对象生命周期和垃圾回收机制。
-
异常处理:
- 学习Java异常体系结构,掌握try-catch-finally块的使用。
- 理解checked异常和unchecked异常的区别。
-
I/O操作:
- 学习File I/O操作,包括文件读写、文件路径操作、目录操作等。
- 理解字节流和字符流的原理及不同之处,掌握BufferedReader、BufferedWriter、FileReader、FileWriter等类的使用。
- 学习网络编程,了解Socket编程基础。
-
多线程编程:
- 掌握线程的创建与销毁、线程状态管理、线程同步机制(如synchronized关键字、wait/notify方法、Lock接口等)。
- 理解线程池和并发工具类的使用(如ExecutorService、CountDownLatch、Semaphore、CyclicBarrier等)。
-
集合框架:
- 深入理解List、Set、Queue、Map等各种集合接口及其常用实现类的特性、操作方法以及它们之间的差异。
- 掌握迭代器、比较器(Comparator)、流(Stream API)的使用。
-
数据库操作:
- 学习SQL基础,能够编写基本的SQL查询语句。
- 掌握Java JDBC API,能够实现数据库连接、查询、插入、删除、更新等操作。
- 熟悉至少一种ORM框架(如Hibernate或MyBatis),能够基于框架进行数据库操作。
-
Web开发基础:
- 理解HTTP协议及请求响应模型。
- 掌握Servlet API,能够编写Servlet程序。
- 学习Spring MVC或Spring Boot框架的基本使用,理解控制器、模型、视图的基本概念。
-
工具与环境:
- 熟悉Eclipse、IntelliJ IDEA等开发工具的使用。
- 学会使用Git或SVN进行版本控制。
- 熟练Linux操作系统的基本命令,能够在Linux环境下部署和运行Java应用。
-
设计模式:
- 了解常见设计模式,如工厂模式、单例模式、观察者模式等,并能在实际项目中适当应用。
-
测试:
- 学习单元测试框架JUnit,能够编写测试用例进行代码验证。
-
Java 8及以上版本的新特性:
- Lambda表达式:掌握Java 8引入的函数式编程特性,能够使用lambda表达式替代匿名内部类,简化代码。
- Stream API:理解并掌握Java 8新增的Stream API,能够进行高效的数据处理、筛选、转换和聚合操作。
- Optional类:了解Optional类的作用,避免空指针异常,并优雅地处理可能不存在的值。
-
模块化系统(Java 9及以上):
- 学习Java模块化系统(Java Platform Module System, JPMS),了解模块声明、模块间的依赖关系以及模块化的优点。
-
并发编程增强:
- 学习CompletableFuture类,实现异步编程和Future模式的改进方案。
- 理解并掌握Java 8新增的并行流(Parallel Streams)。
-
NIO.2(Java 7及以上):
- 掌握非阻塞I/O(Non-blocking I/O, NIO)和通道(Channel)的概念,了解Selector和缓冲区(Buffer)的使用,实现高效的I/O操作。
-
反射与注解:
- 学习Java反射API,能够动态地创建对象、访问私有成员以及操作类的信息。
- 理解注解的定义和使用,如自定义注解以及@Deprecated、@Override等内置注解。
-
软件设计原则与设计模式:
- 了解SOLID原则(单一职责原则、开闭原则、里氏替换原则、接口隔离原则、依赖倒置原则)以及其在实际编程中的应用。
- 对常见的设计模式(如策略模式、装饰器模式、建造者模式、模板方法模式等)有深入理解,并能在项目中恰当运用。
-
JVM优化与性能调优:
- 了解JVM内存结构,掌握JVM参数调优,如-Xms、-Xmx、-XX:NewRatio等。
- 学习JVM垃圾回收机制,如新生代与老年代、Minor GC与Full GC、各种垃圾收集器的特点和选择等。
- 进行性能监控和分析,如使用JConsole、VisualVM等工具查看内存分配、CPU使用率、线程状况等信息。
-
Maven与Gradle构建工具:
- 掌握Maven或Gradle的基本使用,包括项目结构、依赖管理、构建生命周期、插件使用等。
-
持续集成与自动化部署:
- 学习使用Jenkins、GitLab CI/CD或其他CI/CD工具进行持续集成和自动化部署。
总之,Java初级到中级水平的学习是一个全面的过程,不仅限于编程语法本身,还包括了对各种API的理解和应用、设计思想的实践以及相关工具的熟练使用。在实践中不断积累经验,结合具体项目加深对理论知识的理解是至关重要的。
以下是一些初级到中级水平的Java编程经典练习题目,并简要解释思路:
1. 练习1:编写程序输出“Hello, World!”
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
2. 练习2:定义一个整型变量,赋值为100,然后加1并输出
public class Main {
public static void main(String[] args) {
int number = 100;
number++;
System.out.println(number);
}
}
3. 练习3:声明一个数组,存储5个整数,然后遍历并打印数组的所有元素
public class ArrayPractice {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
}
}
4. 练习4:定义一个方法,接受两个整数参数,返回它们的和
public class SumCalculator {
public static int addNumbers(int a, int b) {
return a + b;
}
public static void main(String[] args) {
System.out.println(addNumbers(10, 20)); // 输出30
}
}
5. 练习5:实现一个简单的条件判断,如果用户输入的年龄大于等于18岁,则输出“成年人”,否则输出“未成年人”
import java.util.Scanner;
public class AgeChecker {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入您的年龄:");
int age = scanner.nextInt();
if (age >= 18) {
System.out.println("成年人");
} else {
System.out.println("未成年人");
}
}
}
6. 练习6:实现一个简单的for-each循环遍历String数组并打印
public class ForEachLoop {
public static void main(String[] args) {
String[] names = {"Alice", "Bob", "Charlie"};
for (String name : names) {
System.out.println(name);
}
}
}
请根据这些基础练习自行拓展和深化练习内容,逐步提高编程技能。对于进阶练习,可以从数据结构(如链表、队列、栈、树等)、算法(排序、查找、递归等)、面向对象编程(类与对象、继承、多态等)等方面进行训练。每一道题目的解答都要力求清晰、易懂,并理解背后的设计思路和编程原理。
7. 练习7:创建一个方法,用于计算一个整数数组的平均值
public class AverageCalculator {
public static double calculateAverage(int[] numbers) {
int sum = 0;
for (int number : numbers) {
sum += number;
}
return (double) sum / numbers.length;
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
System.out.println("平均值为:" + calculateAverage(nums));
}
}
8. 练习8:实现二分查找算法在一个有序整数数组中查找给定值
public class BinarySearch {
public static int binarySearch(int[] sortedArray, int target) {
int left = 0;
int right = sortedArray.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (sortedArray[mid] == target) {
return mid;
} else if (sortedArray[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // 如果没找到,返回-1
}
public static void main(String[] args) {
int[] sortedArray = {1, 3, 5, 7, 9, 11};
int target = 7;
int result = binarySearch(sortedArray, target);
if (result != -1) {
System.out.println("找到元素 " + target + ",其索引为 " + result);
} else {
System.out.println(target + " 不在数组中");
}
}
}
9. 练习9:实现一个简单的银行账户类,具有存款、取款和查询余额的功能
public class BankAccount {
private double balance;
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public void deposit(double amount) {
balance += amount;
}
public boolean withdraw(double amount) {
if (amount <= balance) {
balance -= amount;
return true;
} else {
System.out.println("余额不足,取款失败!");
return false;
}
}
public double getBalance() {
return balance;
}
public static void main(String[] args) {
BankAccount account = new BankAccount(1000);
account.deposit(500);
System.out.println("存款后余额为:" + account.getBalance());
account.withdraw(200);
System.out.println("取款后余额为:" + account.getBalance());
}
}
以上只是冰山一角,你还可以通过设计实现更复杂的类、进行异常处理、文件读写操作、多线程编程等来增加练习难度和深度。记住,编程不仅仅是写代码,更重要的是理解背后的逻辑和解决问题的方法。不断挑战自己,多思考、多动手实践,你的Java编程能力会逐渐提高。
接下来再为您提供几个进阶的Java编程练习题目:
10. 练习10:实现一个栈数据结构
```java
public class Stack {
private Object[] stackArray;
private int top;
public Stack(int size) {
stackArray = new Object[size];
top = -1;
}
public void push(Object item) {
if (top >= stackArray.length - 1) {
throw new IllegalStateException("栈已满");
}
top++;
stackArray[top] = item;
}
public Object pop() {
if (top < 0) {
throw new NoSuchElementException("栈为空");
}
Object item = stackArray[top];
stackArray[top--] = null; // 清除引用,帮助垃圾回收
return item;
}
public boolean isEmpty() {
return top == -1;
}
public int size() {
return top + 1;
}
public static void main(String[] args) {
Stack myStack = new Stack(5);
myStack.push("First");
myStack.push("Second");
System.out.println("当前栈大小:" + myStack.size());
System.out.println("弹出元素:" + myStack.pop());
System.out.println("是否为空:" + myStack.isEmpty());
}
}
// 注意:在实际项目中,建议使用泛型(Generic)以避免类型安全问题,例如 `public class Stack<T> {...}`
```
11. 练习11:实现一个队列数据结构(先进先出,FIFO)
```java
public class Queue {
private Object[] queueArray;
private int front, rear;
public Queue(int capacity) {
queueArray = new Object[capacity];
front = 0;
rear = -1;
}
public void enqueue(Object item) {
if ((rear + 1) % queueArray.length == front) {
throw new IllegalStateException("队列已满");
}
rear = (rear + 1) % queueArray.length;
queueArray[rear] = item;
}
public Object dequeue() {
if (front == rear) {
throw new NoSuchElementException("队列为空");
}
Object item = queueArray[front];
queueArray[front] = null;
front = (front + 1) % queueArray.length;
return item;
}
public boolean isEmpty() {
return front == rear;
}
public int size() {
return ((rear - front + queueArray.length) % queueArray.length);
}
public static void main(String[] args) {
Queue myQueue = new Queue(5);
myQueue.enqueue("First");
myQueue.enqueue("Second");
System.out.println("当前队列大小:" + myQueue.size());
System.out.println("出队元素:" + myQueue.dequeue());
System.out.println("是否为空:" + myQueue.isEmpty());
}
}
// 同样,实际项目中推荐使用泛型版本 `public class Queue<T> {...}`
```
12. 练习12:实现一个基于链表的单向列表类
```java
public class LinkedListNode {
Object data;
LinkedListNode next;
public LinkedListNode(Object data) {
this.data = data;
this.next = null;
}
}
public class LinkedList {
private LinkedListNode head;
public void add(Object data) {
LinkedListNode newNode = new LinkedListNode(data);
if (head == null) {
head = newNode;
} else {
LinkedListNode current = head;
while (current.next != null) {
current = current.next;
}
current.next = newNode;
}
}
public void printList() {
LinkedListNode temp = head;
while (temp != null) {
System.out.print(temp.data + " -> ");
temp = temp.next;
}
System.out.println("NULL");
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("One");
list.add("Two");
list.add("Three");
list.printList();
}
}
```
这些练习有助于加深对基础数据结构的理解,并掌握如何在Java中实现它们。同时,也可以尝试实现更复杂的数据结构,如树、图等,并考虑如何优化性能和处理边界情况。
13. 练习13:实现一个简单的计算器,支持加减乘除四则运算
```java
import java.util.Scanner;
public class SimpleCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入第一个数字:");
double num1 = scanner.nextDouble();
System.out.println("请输入运算符(+、-、*、/):");
char operator = scanner.next().charAt(0);
System.out.println("请输入第二个数字:");
double num2 = scanner.nextDouble();
switch (operator) {
case '+':
System.out.printf("结果是:%.2f\n", num1 + num2);
break;
case '-':
System.out.printf("结果是:%.2f\n", num1 - num2);
break;
case '*':
System.out.printf("结果是:%.2f\n", num1 * num2);
break;
case '/':
if (num2 != 0) {
System.out.printf("结果是:%.2f\n", num1 / num2);
} else {
System.out.println("错误:除数不能为零!");
}
break;
default:
System.out.println("错误:无效的运算符!");
}
}
}
14. 练习14:实现斐波那契数列
```java
public class FibonacciSeries {
public static void printFibonacci(int n) {
long prevPrev = 0;
long prev = 1;
System.out.print(prevPrev + ", " + prev + ", ");
for (int i = 2; i < n; i++) {
long current = prevPrev + prev;
System.out.print(current + ", ");
prevPrev = prev;
prev = current;
}
}
public static void main(String[] args) {
int limit = 10;
System.out.print("前 " + limit + " 项斐波那契数列是:");
printFibonacci(limit);
}
}
15. 练习15:实现一个简单的学生类,包含姓名、年龄、成绩等属性以及显示学生信息的方法
```java
public class Student {
private String name;
private int age;
private double grade;
public Student(String name, int age, double grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
public void displayStudentInfo() {
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("成绩:" + grade);
}
public static void main(String[] args) {
Student student = new Student("张三", 20, 90.5);
student.displayStudentInfo();
}
}
持续进行这些练习,并尝试将所学的知识运用到更复杂的场景中,如实现排序算法、数据结构的增删查改操作、文件读写操作、图形用户界面(GUI)设计等,从而不断提高Java编程技能。
16. 练习16:实现一个简易的图书管理系统
```java
class Book {
String title;
String author;
int publicationYear;
Book(String title, String author, int publicationYear) {
this.title = title;
this.author = author;
this.publicationYear = publicationYear;
}
@Override
public String toString() {
return "Title: " + title + ", Author: " + author + ", Publication Year: " + publicationYear;
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class LibrarySystem {
List<Book> books;
public LibrarySystem() {
books = new ArrayList<>();
}
public void addBook(Book book) {
books.add(book);
}
public void removeBook(Book book) {
books.remove(book);
}
public void printAllBooks() {
for (Book book : books) {
System.out.println(book);
}
}
public static void main(String[] args) {
LibrarySystem library = new LibrarySystem();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n请选择操作:\n1. 添加图书\n2. 删除图书\n3. 显示所有图书\n4. 退出系统");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
System.out.println("请输入书名、作者和出版年份(逗号分隔):");
String input = scanner.nextLine();
String[] details = input.split(",");
Book book = new Book(details[0], details[1], Integer.parseInt(details[2]));
library.addBook(book);
break;
case 2:
System.out.println("请输入要删除的书名:");
String titleToRemove = scanner.nextLine();
for (Book book : library.books) {
if (book.title.equals(titleToRemove)) {
library.removeBook(book);
System.out.println("图书已成功删除.");
break;
}
}
if (library.books.stream().noneMatch(b -> b.title.equals(titleToRemove))) {
System.out.println("未找到该图书.");
}
break;
case 3:
library.printAllBooks();
break;
case 4:
System.out.println("系统已退出...");
return;
default:
System.out.println("无效的选择,请重新输入.");
}
}
}
}
17. 练习17:实现一个简单的单链表,并支持插入和删除节点
```java
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
this.next = null;
}
}
public class LinkedListOperations {
public ListNode insert(ListNode head, int value) {
ListNode newNode = new ListNode(value);
if (head == null) {
head = newNode;
} else {
ListNode current = head;
while (current.next != null) {
current = current.next;
}
current.next = newNode;
}
return head;
}
public ListNode deleteNode(ListNode head, int value) {
if (head == null) return null;
if (head.val == value) return head.next;
ListNode current = head;
while (current.next != null) {
if (current.next.val == value) {
current.next = current.next.next;
return head;
}
current = current.next;
}
return head;
}
public void printLinkedList(ListNode head) {
ListNode node = head;
while (node != null) {
System.out.print(node.val + " -> ");
node = node.next;
}
System.out.println("null");
}
public static void main(String[] args) {
LinkedListOperations operations = new LinkedListOperations();
ListNode head = null;
head = operations.insert(head, 1);
head = operations.insert(head, 2);
head = operations.insert(head, 3);
operations.printLinkedList(head);
head = operations.deleteNode(head, 2);
operations.printLinkedList(head);
}
}
```
这些练习可以帮助你巩固面向对象编程、数据结构、控制流等基础知识,并逐步提升对复杂系统的理解和设计能力。后续可以尝试实现更复杂的数据结构、算法,以及利用Java特性如集合框架、多线程等进行实战演练。
18. 练习18:实现一个优先级队列(基于二叉堆)
```java
class PriorityQueue<Item extends Comparable<Item>> {
private Item[] pq;
private int N = 0;
public PriorityQueue(int capacity) {
pq = (Item[]) new Comparable[capacity + 1];
}
private boolean less(int i, int j) {
return pq[i].compareTo(pq[j]) < 0;
}
private void swap(int i, int j) {
Item t = pq[i];
pq[i] = pq[j];
pq[j] = t;
}
public void insert(Item item) {
pq[++N] = item;
swim(N);
}
public Item delMin() {
Item min = pq[1];
exch(1, N--);
sink(1);
pq[N + 1] = null; // avoid loitering
return min;
}
private void swim(int k) {
while (k > 1 && less(k / 2, k)) {
exch(k / 2, k);
k = k / 2;
}
}
private void sink(int k) {
while (2 * k <= N) {
int j = 2 * k;
if (j < N && less(j, j + 1)) j++;
if (!less(k, j)) break;
exch(k, j);
k = j;
}
}
private void exch(int i, int j) {
swap(i, j);
}
public boolean isEmpty() {
return N == 0;
}
}
public class PriorityQueueTest {
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>(10);
for (int i = 0; i < 10; i++) {
pq.insert(i);
}
while (!pq.isEmpty()) {
System.out.print(pq.delMin() + " ");
}
}
}
19. 练习19:实现一个简单的LRU缓存(Least Recently Used)
```java
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
public class LRUCache<K, V> {
private final int capacity;
private Map<K, Node<K, V>> map;
private Queue<Node<K, V>> queue;
private int size;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>();
this.queue = new LinkedList<>();
}
public V get(K key) {
if (!map.containsKey(key)) return null;
moveToHead(key);
return map.get(key).value;
}
public void put(K key, V value) {
if (map.containsKey(key)) {
moveToHead(key);
map.get(key).value = value;
} else {
if (size == capacity) {
Node<K, V> removedNode = queue.poll();
map.remove(removedNode.key);
size--;
}
Node<K, V> newNode = new Node<>(key, value);
map.put(key, newNode);
queue.offer(newNode);
size++;
}
}
private void moveToHead(K key) {
Node<K, V> node = map.get(key);
queue.remove(node);
queue.offer(node);
}
private static class Node<K, V> {
K key;
V value;
Node(K key, V value) {
this.key = key;
this.value = value;
}
}
public static void main(String[] args) {
LRUCache<Integer, String> cache = new LRUCache<>(2);
cache.put(1, "one");
cache.put(2, "two");
System.out.println(cache.get(1)); // 返回 "one"
cache.put(3, "three"); // 去除 key 2
System.out.println(cache.get(2)); // 返回 null(已移除)
cache.put(4, "four"); // 去除 key 1
System.out.println(cache.get(1)); // 返回 null(已移除)
System.out.println(cache.get(3)); // 返回 "three"
System.out.println(cache.get(4)); // 返回 "four"
}
}
```
这些练习涵盖了数据结构(如二叉堆和双向链表)以及算法(如优先级队列和LRU缓存策略)的实现,对于提升编程技巧和解决问题的能力非常有帮助。
20. 练习20:实现一个简单的数据库连接池
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Queue;
public class ConnectionPool {
private static final int MAX_POOL_SIZE = 10;
private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb";
private static final String USER = "username";
private static final String PASS = "password";
private Queue<Connection> connections;
private int poolSize;
public ConnectionPool() {
connections = new LinkedList<>();
initPool();
}
private void initPool() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
for (int i = 0; i < MAX_POOL_SIZE; i++) {
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
conn.setAutoCommit(false); // 可根据需求设置自动提交
connections.add(conn);
poolSize++;
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
public synchronized Connection getConnection() {
while (poolSize == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Connection conn = connections.poll();
notifyAll(); // 唤醒所有等待的线程
return conn;
}
public synchronized void releaseConnection(Connection conn) {
if (conn != null) {
try {
if (!conn.isClosed()) {
connections.offer(conn);
}
poolSize--;
notifyAll(); // 唤醒所有等待的线程
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ConnectionPool pool = new ConnectionPool();
// 使用getConnection()获取连接,使用完毕后调用releaseConnection()释放连接
}
}
21. 练习21:实现一个简单的文件上传功能(HTTP POST请求)
```java
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class FileUploader {
public static void uploadFile(String serverUrl, String filePath) {
try {
URL url = new URL(serverUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data");
File file = new File(filePath);
Files.copy(file.toPath(), connection.getOutputStream(), StandardCopyOption.REPLACE_EXISTING);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println("文件上传成功");
} else {
System.out.println("文件上传失败,响应码:" + responseCode);
}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String serverUrl = "http://example.com/upload"; // 替换为实际服务器地址
String filePath = "/path/to/your/file.txt"; // 替换为你要上传的文件路径
uploadFile(serverUrl, filePath);
}
}
请注意,上述示例简化了某些细节,实际应用中需处理更多边界情况和错误,例如完善异常处理、关闭资源、加密传输等。在实现数据库连接池时,可选用成熟的开源库如HikariCP或Druid。而在文件上传功能中,通常会使用Apache HttpClient或OkHttp库以支持更复杂的HTTP请求处理和文件上传格式(如Multipart)。
22. 练习22:实现一个简单的文件下载器
```java
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class FileDownloader {
public static void downloadFile(String urlString, String saveDir, String fileName) {
try {
URL url = new URL(urlString);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedInputStream bis = new BufferedInputStream(httpConn.getInputStream());
String saveFilePath = saveDir + File.separator + fileName;
FileOutputStream fos = new FileOutputStream(saveFilePath);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.close();
bis.close();
httpConn.disconnect();
System.out.println("文件已成功下载到:" + saveFilePath);
} else {
System.out.println("无法下载文件,响应码:" + responseCode);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String urlString = "http://example.com/path/to/file.zip"; // 需替换为实际URL
String saveDir = "/path/to/save/directory"; // 替换为本地保存目录
String fileName = "file.zip"; // 文件名
downloadFile(urlString, saveDir, fileName);
}
}
23. 练习23:实现一个简单的哈希表(HashMap)
```java
public class MyHashMap<K, V> {
private static final int INITIAL_CAPACITY = 16;
private static final float LOAD_FACTOR = 0.75f;
private Entry<K, V>[] table;
private int size;
public MyHashMap() {
table = new Entry[INITIAL_CAPACITY];
}
private static class Entry<K, V> {
K key;
V value;
Entry<K, V> next;
Entry(K key, V value, Entry<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
}
public V put(K key, V value) {
int hash = hash(key);
int index = indexFor(hash, table.length);
Entry<K, V> entry = table[index];
while (entry != null) {
if (entry.key.equals(key)) {
V oldValue = entry.value;
entry.value = value;
return oldValue;
}
entry = entry.next;
}
resizeIfNeeded();
entry = new Entry<>(key, value, table[index]);
table[index] = entry;
size++;
return null;
}
public V get(K key) {
int hash = hash(key);
int index = indexFor(hash, table.length);
Entry<K, V> entry = table[index];
while (entry != null) {
if (entry.key.equals(key)) {
return entry.value;
}
entry = entry.next;
}
return null;
}
private void resizeIfNeeded() {
if (size > table.length * LOAD_FACTOR) {
resize(2 * table.length);
}
}
private void resize(int newCapacity) {
Entry<K, V>[] oldTable = table;
table = new Entry[newCapacity];
for (Entry<K, V> entry : oldTable) {
while (entry != null) {
rehash(entry);
entry = entry.next;
}
}
}
private void rehash(Entry<K, V> entry) {
int hash = hash(entry.key);
int index = indexFor(hash, table.length);
entry.next = table[index];
table[index] = entry;
}
private int hash(K key) {
return Math.abs(key.hashCode()) % table.length;
}
private int indexFor(int h, int length) {
return h & (length - 1);
}
// 其他方法如remove、size、isEmpty等可以按照类似的方式实现
public static void main(String[] args) {
MyHashMap<String, Integer> map = new MyHashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
System.out.println(map.get("Apple")); // 输出 1
}
}
```
以上练习涵盖了网络请求、文件操作和数据结构(哈希表)的实现,能够帮助你更好地理解并应用这些关键概念。后续你可以尝试实现哈希表的扩容机制、解决哈希冲突以及优化性能等进阶功能。
24. 练习24:实现一个简单的命令行版文本编辑器
```java
import java.io.*;
public class SimpleTextEditor {
private StringBuilder content;
public SimpleTextEditor() {
content = new StringBuilder();
}
public void readFromFile(String filePath) {
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = br.readLine()) != null) {
content.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeToFile(String filePath) {
try (PrintWriter writer = new PrintWriter(new FileWriter(filePath))) {
writer.print(content.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
public void append(String text) {
content.append(text);
}
public void delete(int startIndex, int endIndex) {
if (startIndex < 0 || startIndex > endIndex || endIndex > content.length()) {
System.out.println("Invalid range");
} else {
content.delete(startIndex, endIndex);
}
}
public void replace(int startIndex, int endIndex, String newText) {
if (startIndex < 0 || startIndex > endIndex || endIndex > content.length()) {
System.out.println("Invalid range");
} else {
content.replace(startIndex, endIndex, newText);
}
}
public void display() {
System.out.println(content.toString());
}
public static void main(String[] args) {
SimpleTextEditor editor = new SimpleTextEditor();
editor.readFromFile("input.txt");
editor.display();
editor.append("\nAppended text.");
editor.replace(0, 5, "Replaced!");
editor.delete(10, 15);
editor.writeToFile("output.txt");
}
}
25. 练习25:实现一个简单的TCP聊天客户端和服务器
```java
// TCP聊天服务器端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("服务器启动,等待客户端连接...");
while (true) {
Socket socket = serverSocket.accept();
new Thread(new ClientHandler(socket)).start();
}
}
static class ClientHandler implements Runnable {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ClientHandler(Socket socket) throws IOException {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
}
@Override
public void run() {
String message;
try {
while ((message = in.readLine()) != null) {
System.out.println("客户端消息:" + message);
// 在这里可以添加转发消息至其他客户端的逻辑
out.println("服务器回复:" + message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
// TCP聊天客户端
import java.io.*;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 12345);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
String messageFromServer, messageToServer;
while (true) {
messageToServer = userInput.readLine();
out.println(messageToServer);
messageFromServer = in.readLine();
System.out.println("服务器消息:" + messageFromServer);
}
}
}
```
以上练习涉及到了文件操作、字符串处理、线程管理和网络通信等方面的知识,通过完成这些练习,你可以进一步提升对Java核心特性的理解和应用能力。
接下来是一些关于Java GUI编程的练习题目:
26. 练习26:使用Java Swing创建一个简单的计时器应用程序
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TimerApp extends JFrame {
private JLabel timerLabel;
private JButton startButton, stopButton;
private int seconds = 0;
private Timer timer;
public TimerApp() {
setTitle("简易计时器");
setSize(300, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
timerLabel = new JLabel("00:00");
startButton = new JButton("开始");
stopButton = new JButton("停止");
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
startTimer();
}
});
stopButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
stopTimer();
}
});
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(timerLabel);
panel.add(startButton);
panel.add(stopButton);
add(panel);
setVisible(true);
}
private void startTimer() {
timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
seconds++;
int mins = seconds / 60;
int secs = seconds % 60;
timerLabel.setText(String.format("%02d:%02d", mins, secs));
}
});
timer.start();
}
private void stopTimer() {
if (timer != null) {
timer.stop();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TimerApp();
}
});
}
}
27. 练习27:使用JavaFX创建一个简单的登录界面
```java
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class LoginApp extends Application {
@Override
public void start(Stage primaryStage) {
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
Label usernameLabel = new Label("用户名:");
TextField usernameField = new TextField();
grid.add(usernameLabel, 0, 0);
grid.add(usernameField, 1, 0);
Label passwordLabel = new Label("密码:");
PasswordField passwordField = new PasswordField();
grid.add(passwordLabel, 0, 1);
grid.add(passwordField, 1, 1);
Button loginButton = new Button("登录");
grid.add(loginButton, 1, 2);
Scene scene = new Scene(grid, 300, 200);
primaryStage.setTitle("简易登录界面");
primaryStage.setScene(scene);
primaryStage.show();
// 添加登录按钮点击事件监听器,验证用户名和密码(此处仅为模拟,实际需要与后台交互)
loginButton.setOnAction(e -> {
String username = usernameField.getText();
String password = passwordField.getText();
if ("admin".equals(username) && "123456".equals(password)) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
});
}
public static void main(String[] args) {
launch(args);
}
}
```
以上练习旨在帮助你熟悉Java的Swing和JavaFX GUI编程库,掌握如何构建基本的桌面应用程序界面以及处理用户交互。在实际开发中,可以根据项目需求深入学习布局管理、事件处理、模型视图控制器(MVC)模式等内容。
28. 练习28:实现一个简单的生产者消费者模型
```java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProducerConsumer {
private final Queue<Integer> buffer = new LinkedList<>();
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final int BUFFER_SIZE = 10;
class ProducerThread extends Thread {
@Override
public void run() {
Random random = new Random();
while (true) {
lock.lock();
try {
while (buffer.size() == BUFFER_SIZE) {
notFull.await();
}
buffer.add(random.nextInt(100));
System.out.println("Producer produced: " + buffer.peek());
notEmpty.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
class ConsumerThread extends Thread {
@Override
public void run() {
while (true) {
lock.lock();
try {
while (buffer.isEmpty()) {
notEmpty.await();
}
int data = buffer.poll();
System.out.println("Consumer consumed: " + data);
notFull.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
ProducerConsumer pc = new ProducerConsumer();
Thread producer = new pc.ProducerThread();
Thread consumer = new pc.ConsumerThread();
producer.start();
consumer.start();
}
}
29. 练习29:实现一个简单的Future模式,异步获取结果
```java
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FuturePatternExample {
interface DataFetcher {
String fetchData() throws Exception;
}
static class AsyncDataFetcher {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<String> fetchAsyncData(DataFetcher dataFetcher) {
return executorService.submit(dataFetcher::fetchData);
}
}
public static void main(String[] args) {
AsyncDataFetcher asyncDataFetcher = new AsyncDataFetcher();
DataFetcher dataFetcher = () -> {
Thread.sleep(2000); // 模拟耗时操作
return "Fetched Data!";
};
Future<String> future = asyncDataFetcher.fetchAsyncData(dataFetcher);
try {
System.out.println("Doing some other tasks...");
Thread.sleep(1000);
System.out.println("Received data from the Future: " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
这两个练习将帮助你掌握Java中的并发工具类和接口,如ReentrantLock
, Condition
, ExecutorService
, 和 Future
,以便更好地进行多线程编程和异步任务处理。在实际项目中,合理地运用并发技术能有效提高程序执行效率和响应速度。
下面是另一个关于Java集合框架和流API的练习题目:
30. 练习30:使用Java 8 Stream API对集合进行操作
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamAPITest {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
// 示例1:过滤出长度大于5的单词,并转换为大写
List<String> longWordsInUppercase = words.stream()
.filter(word -> word.length() > 5)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(longWordsInUppercase); // 输出:[BANANA, ELDERBERRY]
// 示例2:统计列表中每个单词的字符数,并按字符数从低到高排序
List<Integer> wordLengthsSorted = words.stream()
.mapToInt(String::length)
.boxed()
.sorted()
.collect(Collectors.toList());
System.out.println(wordLengthsSorted); // 输出:[5, 5, 6, 6, 10]
// 示例3:将单词列表合并为一个字符串,单词之间用逗号分隔
String concatenatedWords = words.stream()
.collect(Collectors.joining(", "));
System.out.println(concatenatedWords); // 输出:apple, banana, cherry, date, elderberry
// 示例4:计算列表中单词的总字符数
int totalCharacters = words.stream()
.mapToInt(String::length)
.sum();
System.out.println(totalCharacters); // 输出:28
}
}
这个练习将帮助你熟练掌握Java 8引入的Stream API,学会如何对集合进行高效且简洁的操作,包括过滤、映射、排序、聚合等多种函数式编程特性。通过使用Stream API,可以使代码更加清晰易读,同时也提升了代码的运行效率。
此外,也可以尝试实现更复杂的流操作,比如找出列表中的最大值、最小值、平均值,或者使用reduce方法进行聚合运算等。在实际项目中,合理利用Stream API可以极大地提升数据处理和业务逻辑实现的效率。
综上所述,从初级到中级的Java程序员需要逐步掌握以上各项技能,同时注重实践,在项目中灵活运用所学知识,不断提升自己的编码能力和问题解决能力。此外,保持对新技术的关注和学习,如Spring Boot、Spring Cloud微服务架构等,也是成长为一名优秀Java开发者的重要环节。
python推荐学习汇总连接:
[50个开发必备的Python经典脚本(1-10)](https://blog.csdn.net/qqrrjj2011/article/details/135201319)
[50个开发必备的Python经典脚本(11-20)](https://blog.csdn.net/qqrrjj2011/article/details/135220796)
[50个开发必备的Python经典脚本(21-30)](https://blog.csdn.net/qqrrjj2011/article/details/135220906)
[50个开发必备的Python经典脚本(31-40)](https://blog.csdn.net/qqrrjj2011/article/details/135222295)
[50个开发必备的Python经典脚本(41-50)](https://blog.csdn.net/qqrrjj2011/article/details/135222681)
————————————————
**最后我们放松一下眼睛**
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/25f61fadc35f491dae24742ab85fd90a.png)