理解不到位以及有很多不全面,不得不感叹学无止境啊

何为编程?

我认为编程是人与计算机打交道,通过编写代码和计算机交互让它为我们服务(解决问题)

什么是Java?

Java是一门面向对象的编程语言,它摒弃了C中指针以及C++中的多继承等概念。因此功能强大,简单易用是其两大特征,它还是静态面向对象编程的代表。

JVM、JRE、JDK是什么以及关系

JVM(Java Virtual Machine) --- java虚拟机:提供执行字节码文件的能力

JRE(Java Runtime Environment) --- java运行时环境:包含了java虚拟机以及核心类库(一些基础库)

JDK(Java Development Kit) --- java开发工具:包含JRE的开发工具(里面有编译工具-javac.exe 打包工具-jar.exe )

Java语言特点

简单易用
跨平台性
面向对象(继承、封装、多态)
支持网络编程--------IO
支持多线程-----------Thread、锁、线程池
健壮性-----------强类型机制、异常处理、垃圾回收机制
安全性-----------初学时虽然一直知道java是一门安全的语言,但怎么个安全法,就不是很清楚:不支持指针(防止随意操作内存)、安全检测、垃圾回收、异常处理

Java的跨平台性的理解

可在多个系统平台上运行,也就是说只要能够在平台上安装虚拟机(通过Java文件一次编译后转化成字节码文件)就能运行Java程序(也就是在虚拟机上运行那些字节码文件)

什么是字节码---- .class文件

tip:编译器有两处,一处是在类加载器中将Java文件编译成.class文件(字节码文件),另一处是在执行引擎中,将虚拟机中的代码(虚拟机理解的代码)转化为机器才能看懂的机器语言(这个貌似叫解释器)
在这里插入图片描述
这里可以理解是在应用程序与操作系统中加了一层(这里让我想到一句话,大概意思是没有什么是再加一层不能解决的)

Java程序主类

包含main方法,且只能有一个主类
应用程序的主类不一定要求是public
主类是程序执行的入口
小程序主类是继承自系统类JApplet或Applet的子类

Java和C++的区别

都是面向对象支持三大特性(封装、继承、多态)
Java是单继承 C++支持多重继承(Java虽然只支持单继承,但接口可以多实现)
Java没有指针(不提供指针来直接访问内存,程序内存更加安全)
Java有自动内存管理机制,不需要程序员手动释放无用内存

Java的数据类型

Java语言是强类型语言

分类:
    基本数据类型:
            数值型:
                整数型:byte、short、int、long
                浮点型:float、double
            字符型:char
            布尔型:boolean
    引用数据类型:
            类:class
            接口:interface
            数据:[]
基本类型图
    byte 1字节        -2^7 ~ 2^7-1
    short 2字节        -2^15 ~ 2^15-1
    int 4字节        -2^31 ~ 2^31-1
    long 8字节        -2^63 ~ 2^63-1
    float 4字节        单精度浮点数
    double 8字节    双精度浮点数
    char 2字节
    boolean 1字节

switch是否能作用在byte、long、String上

Java5之前 switch(expr)中 expr可以是byte、short、char、int,后面引入了枚举enum,Java7开始可以是String
总结:byte、short、char、int、enum、String可以
就long不可以

访问修饰符:

private 同一类可见
default 同一包内可见(不包括子类 其他包)
protected 同一包内的类和所有子类可见(包括其他包下的子类)
public 所有类可见

final有什么用?

被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变(引用不可变,但是引用指向的内容是可以改变的,但如果是基本类型,则在初始化后便不能改变)

final:修饰类、变量、方法(不能被继承、不能重写、不能被重新赋值)
finally:try-catch代码块后一定会执行的那部分
finalize:是一个方法用于垃圾回收时判断一个对象是否可回收

this关键字

可以理解为指向对象本身的一个指针

super关键字

可以理解为只想自己超(父)类的一个指针(这里我在想父类难道不是只是一个类而非实例对象吗?但是结合之前静态块和构造方法让我发现当你在new一个子类的时候不仅仅是创建一个子类对象,也间接创建了一个父类对象,所以你会发现运行时会存在父类的静态块和构造方法,也说明了super为何存在,因为其已经被放入堆中)

super()和this()均需放在构造方法内第一行,且不能出现在构造函数中

staic存在的意义

创建独立于具体对象的域变量或者方法(这里让我想到了方法区也就是在所谓的元空间中存在静态变量)以致于即使没有创建对象也能使用属性和调用方法
静态代码块 ---- 优化程序性能(只会执行一次)

static注意事项

1.静态只能访问静态
2.非静态既可以访问非静态的,也可以访问静态的

面向过程

性能高,因为类调用时需要实例化,开销比较大

面向对象

易维护、易复用、易扩展,使系统更加灵活

面向对象是模型化 --- 抽象出一个类

底层其实还是面向过程-----联想MVC 因为之前是整体架构 然后就抽象出三个块

面向对象的三大特性

封装:能够对外选择隐藏对象的属性和实现仅提供公共访问方式(public、private....这些修饰符可以看出)

继承:使用已存在的类的定义作为基础创建新的类(单继承)(为了提高代码的复用,同时继承是多态的前提)
例如:

    --哈士奇
狗    --金毛
    --边牧
大家都是狗 存在狗的普遍特征,同时又有自己的特征
----过于抽象 自己想象----

关于继承需要注意的点:

1.子类拥有父类非private的属性和方法
2.子类可拥有自己的属性和方法,即扩展
3.重写---用自己的方式去实现父类方法

多态----->以继承为前提,三个必要条件:继承、重写、向上转型
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,提高程序的扩展性
例如:Animal dog = new Dog() 这就是典型多态的体现
这样,不用修改源代码就让引用变量绑定在不同的类实现上,从而导致该引用调用的具体方法随之改变,让程序可以选择多个运行状态

面向对象的五大基本原则

单一职责原则 SRP
开放封闭原则 OCP
里氏替换原则 LSP 子类替换父类
依赖倒置原则 DIP 抽象不应该依赖于具体实现,该反过来
接口分离原则 ISP 拆分功能接口

接口和抽象的那些事

抽象类可以有构造器 / 接口不能有构造器
抽象类中的方法可以是任意访问修饰符 / 接口默认是public 不允许private、protected
抽象类的字段声明可以是任意的 / 接口字段默认都是static和final

java8后接口引入了默认方法(default)和静态方法(static)

抽象类不能用final修饰(本就用于让别人继承)

重载和重写那些事

重载:发生在同一个类中,方法名相同参数列表不同(类型、个数、顺序)与返回值、修饰符无关
重写:发生在子类中,方法名参数相同,内容不同(如果父类方法访问符是private则子类无法重写)

== 和 equals

==比较的是地址,也就是对象的引用是否相等
equals是Object自带的一个方法在你没重写前作用适合 == 是一样的,比较的是地址。
但是我们经常会去重写这个方法 如(String.equals) 这时比较的就是内容了

这里String中的重写就是先通过instanceof来判断类型是否一样,然后判断字符串的长度是否相等,最后通过将两边的字符数组每个取出来比较来判断

HashCode()方法

hashCode()这个方法Object就有,所以基本所有的类都自带hashCode方法

-散列表---这让我想起了hashmap
hashCode()可用于检查重复 例:HashSet -> 先计算hashCode来判断加入位置,同时与其他已加入的对象的hashCode值进行比较,如果没有相符的hashCode,HashSet就会假设对象没有重复出现。如果有相同的hashCode就会去比较对象内容,相同就不会让他添加成功,如果不同 ,重新散列到其他位置
总结:hashCode用于标明存放位置、查重

两个对象相等 hashCode一定相同
hashCode相同 两个对象不一定相等

值传递

Java语言的方法调用只支持参数的值传递
普通值(普通基本类型参数) 传的是拷贝
传对象则是传的引用(引用的拷贝 都指向堆中的同一实例)能改变其中的属性

JDK常用包

lang、io、nio、net、util、sql

IO流(这部分没怎么了解)

Java中IO流分为几种:
    流动分:输入流  输出流
    操作单元分:字节流  字符流
    流的角色分:节点流  处理流

4个基本的抽象类-----派生出了IO流的40多个类
InputStream/Reader:所有的输出流的基类,前者是字节输入流后者是字符输入流
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流

BIO:同步阻塞I/O模型
NIO:同步非阻塞IO模型
AIO:异步非阻塞IO模型

Files常用的方法

exists()
creatFile()
createDirectory()
delete()
copy()
move()
size()
read()
write()

什么是反射机制

  我个人认为是能够在运行期间获取方法区中类信息以及堆中对象并进行调用--类似运行中能去调用虚拟机中的字节码

  是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个类,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制
Spring的XML以及JDBC Class.forName() 就是使用了反射机制

反射修改所谓的"不可变"对象

什么意思?
final修饰的变量不可变是指其引用不可改变,而反射则是可以直接通过虚拟机将引用内            存中的内容改变
引用还是那个引用,但内容已经变了

String

字符串常量 ---元空间(逻辑上存在 物理上不存在) 堆内存中
  可以提高内存的使用率:在创建字符串时JVM会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用(其实这里有个概念不是很清楚,那就是字面量)
  这里会分开来看,如果这里使用的是使用字面量的String 如String a = "abc" 会先去看字符串常量池中是否存在,没有就创建一个“abc”并返回常量池中的引用,有则直接返回引用。
  而通过new String()来创建的话则是先去常量池中看是否存在,如果存在就在堆中去创建并返回引用,如果不存在就先在常量池中创建一个然后再去堆中创建(这里虽然最后都返回的是堆中的引用,但如果常量池中没有会创建两次)

String不是基本数据类型

String不可变----底层是一个final char[]数组---但是引用可变
例如:

String str = "hello";
str = str + "world";
System.out.println("str:" + str);

str ->hello world
实际上原来String内容是不变的(还是在常量池中)只是str指向的内存地址转为了新创建的“hello world”的内存地址而已,也就是说字符串常量池中开辟了块内存区域给"hello world"

String不可被继承

String常用方法:
    indexOf():返回指定字符的索引
    charAt():返回指定索引处的字符
    replace():替换字符串
    trim():去除字符串两端的空白
    split():分割字符串,返回字符数组
    subString():截取字符串
    reverse():字符串反转
    toUpperCase():转大写
    toLowerCase():转小写
    toCharArray():获取字符数组

StringBuffer、StringBuilder与String的区别

其中StringBuffer、StringBuilder都是继承于AbstarctStringBuilder类
其中使用char[] value ,所以是可变的
StringBuffer对方法加了同步锁(sychronized)所以线程安全
StringBuilder没有加锁,线程不安全,所以性能要高一点 (与StringBuffer只差10%~15%的性能)
性能:
    StringBuilder > StringBuffer > String

自动装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来
拆箱:将包装类型转化为基本数据类型
Byte - byte
Short - short
Integer - int
Long - long
Float - float
Double - double
Char - char
Boolean - boolean

其中有意思的是Integer值在-128 ~ 127之间时不会去new Integer对象,而是直接引用常量池中的值 类似于之前的String吧 Integer a = 1; Integer b = 1;
a == b true