目录
一、工作领域
企业级系统
Web开发领域
android平台应用
大数据平台开发
二、语言特性
1. 简单性
2. 面相对象
3. 分布式(微服务)
4. 健壮性
5. 安全性
6. 体系结构中立
7. 可移植性
8. 解释性
9. 高性能
10. 多线程
11. 动态性
三、Java的程序结构
四、Java的程序运行
五、标识符
六、关键字
七、初始集合框架
1、什么是集合框架
2. 背后所涉及的数据结构以及算法
2.1 什么是数据结构
2.2 容器背后对应的数据结构
2.3 相关java知识
2.4 什么是算法
八、时间和空间复杂度
1、时间复杂度
1.1概念
1.2大O的渐进表示法
1.3常见时间复杂度计算举例
2.空间复杂度
2.1概念
- 运行时堆栈溢出。蠕虫和病毒常用的攻击手段。
- 破坏自己进程空间之外的内存。
- 未经授权读写文件
而且其他语言编写的程序,在编译后如果能够严格按照字节码文件的规范生成.class文件,也可以在JVM上运行。
1.源文件(扩展名为*.java):源文件带有类的定义。类用来表示程序的一个组件,小程序或许只会有一个类。类的内容必须包含在花括号里面。2.类:类中带有一个或多个方法。方法必须在类的内部声明。3.方法:在方法的花括号中编写方法应该执行的语句。总结一下:类存在于源文件里面;方法存在于类中;语句存在于方法中。
注意:在运行Java程序前,必须先安装好JDK(Java Development Kit即Java开发工具包),JDK里面就包含了javac和java工具,Java程序最终是在JVM(Java虚拟机)中运行的。
- JDK(Java Development Kit):Java开发工具包,提供给Java程序员使用,包含了JRE,同时还包含了编译 器javac与自带的调试工具Jconsole、jstack等。
- JRE(Java Runtime Environment):Java运行时环境,包含了JVM,Java基础类库。是使用Java语言编写程序运行的所需环境。
- JVM:Java虚拟机,运行Java代码
Trail: Collections (The Java™ Tutorials) (oracle.com)https://docs.oracle.com/javase/tutorial/collections/index.html
1. 泛型 Generic2. 自动装箱 autobox 和自动拆箱 autounbox3. Object 的 equals 方法4. Comparable 和 Comparator 接口
// 请计算一下func1基本操作执行了多少次?
void func1(int N)
{ int count = 0;
for (int i = 0; i < N ; i++)
{
for (int j = 0; j < N ; j++)
{
count++;
}
}
for (int k = 0; k < 2 * N ; k++)
{
count++;
}
int M = 10;
while ((M--) > 0)
{
count++;
}
System.out.println(count);
}
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。
// 计算func2的时间复杂度?
void func2(int N)
{
int count = 0;
for (int k = 0; k < 2 * N ; k++)
{
count++;
}
int M = 10;
while ((M--) > 0)
{
count++;
}
System.out.println(count);
}
// 计算func3的时间复杂度?
void func3(int N, int M)
{ int count = 0;
for (int k = 0; k < M; k++)
{
count++;
}
for (int k = 0; k < N ; k++)
{
count++;
}
System.out.println(count);
}
// 计算func4的时间复杂度?
void func4(int N)
{
int count = 0;
for (int k = 0; k < 100; k++)
{
count++;
}
System.out.println(count);
}
// 计算bubbleSort的时间复杂度?
void bubbleSort(int[] array)
{
for (int end = array.length; end > 0; end--)
{
boolean sorted = true;
for (int i = 1; i < end; i++)
{
if (array[i - 1] > array[i])
{
Swap(array, i - 1, i);
sorted = false;
}
}
if (sorted == true)
{
break;
}
}
}
// 计算binarySearch的时间复杂度?
int binarySearch
(
int[] array, int value)
{
int begin = 0;
int end = array.length - 1;
while (begin <= end)
{
int mid = begin + ((end-begin) / 2);
if (array[mid] < value)
begin = mid + 1;
else if
(array[mid] > value) end = mid - 1;
else
return mid;
}
return -1;
}
// 计算阶乘递归factorial的时间复杂度?
long factorial(int N)
{
return N < 2 ? N : factorial(N-1) * N;
}
// 计算斐波那契递归fibonacci的时间复杂度?
int fibonacci(int N)
{
return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}
【 实例答案及分析 】1. 实例 1 基本操作执行了 2N+10 次,通过推导大 O 阶方法知道,时间复杂度为 O(N)2. 实例 2 基本操作执行了 M+N 次,有两个未知数 M 和 N ,时间复杂度为 O(N+M)3. 实例 3 基本操作执行了 100 次,通过推导大 O 阶方法,时间复杂度为 O(1)4. 实例 4 基本操作执行最好 N 次,最坏执行了 (N*(N-1))/2 次,通过推导大 O 阶方法 + 时间复杂度一般看最坏,时间复杂度为 O(N^2)5. 实例 5 基本操作执行最好 1 次,最坏次,时间复杂度为 O( log2N)ps: 在算法分析中表示是底数 为 2 ,对数为 N ,有些地方会写成 lgN 。(建议通过折纸查找的方式讲解 logN 是怎么计算出来的) ( 因为二分查找每次排除掉一半的不适合值, 一次二分剩下: n/2两次二分剩下: n/2/2 = n/4)6. 实例 6 通过计算分析发现基本操作递归了 N 次,时间复杂度为 O(N) 。7. 实例 7 通过计算分析发现基本操作递归了2的N次方次,时间复杂度为O(2的N次方 )。(建议画图递归栈帧的二叉树讲解)
2.2举例
// 计算bubbleSort的空间复杂度?
void bubbleSort(int[] array)
{
for (int end = array.length; end > 0; end--)
{
boolean sorted = true;
for (int i = 1; i < end; i++)
{
if (array[i - 1] > array[i])
{
Swap(array, i - 1, i);
sorted = false;
}
}
if (sorted == true)
{
break;
}
}
}
// 计算fibonacci的空间复杂度?
int[] fibonacci(int n)
{
long[] fibArray = new long[n + 1];
fibArray[0] = 0;
fibArray[1] = 1;
for (int i = 2; i <= n ; i++)
{
fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
}
return fibArray;
}
// 计算阶乘递归Factorial的空间复杂度?
long factorial(int N)
{
return N < 2 ? N : factorial(N-1)*N;
}
【 实例答案及分析 】1. 实例 1 使用了常数个额外空间,所以空间复杂度为 O(1)2. 实例 2 动态开辟了 N 个空间,空间复杂度为 O(N)3. 实例 3 递归调用了 N 次,开辟了 N 个栈帧,每个栈帧使用了常数个空间。空间复杂度为 O(N)