同步操作将从 duanchaojie/JavaCode 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
[toc]
学习java过程中所敲的代码和笔记
任何
数据类型),以及基本数据类型(char \u0000)和引用数据类型的默认值,二维数据的在堆栈的内存分布情况,数组的工具类Arrays的常用方法:equals,fill,sort,toString;random.nextInt(10) + 20;
[20,30),不给值默认再int范围内随机生产;
3. 字符串常量池:程序中直接写上上引号的字符串,就存储在字符串常量池中。
Arrays.sort(strArray, Collections.reverseOrder())
降序排序(Arrays.sort()默认是升序);System.arraycopy(Object src,srcPos,Object dest,destPos,length)
getPackage()
获取此类的包,也可以通过Class对象获取成员变量们,成员方法们,构造方法们;(参数类型 参数名称) ‐> { 代码语句 }
对象:: 实例方法名
类:: 静态方法名
类:: 实例方法名
枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
,Enum类.values()获取枚举类型的对象数组,Enum类.valueOf(String str)把一个字符串转为对应的枚举类对象;、
TreeMap和
Properties},Collection接口{List接口(元素有序、元素可重复:ArrayList,LinkedList,Vector),Set接口(元素无序,而且不可重复:HashSet-->LinkedHashSet,TreeSet)}接口与
Map接口主要用于存储元素,而
Iterator 主要用于迭代访问(即遍历)
,Collection.iterator()获取迭代器,常用方法:it.hasNext(),it.next();泛型的好处:将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
泛型的上限: <? extends 类 >
,泛型的下限: <? super 类 >
;饿汉式,
直接创建一个初始容量为10的数组;JDK1.8ArrayList像懒汉式,
一开始创建一个长度为0的数组,当添加第一个元素时再创建一个始容量为10的数组。元素是不可重复
的,集合元素可以为null
,线程不安全
(底层HashMap);当一个类有自己特有的“逻辑相等”概念,
当改写equals()的时候,总是要改写hashCode(),根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode()方法,它们仅仅是两个对象。所以复写equals方法的时候一般都需要同时复写hashCode方法。System.getProperties
方法就是返回一个 Properties
对象。
stringPropertyNames()
:所有键的名称的集合。java.io.File
类是文件和目录路径名的抽象表示,开发路径使用/,File类构造器有:File(path/parent,child/File parent,String child)
File类常用方法有:getAbsolutePath(),getPath(),getName(),length(字节),exists(文件/文件夹是否存在),isDirectory(),isFile(),createNewFile(不存在才创建),delete(),mkdir(),mkdirs(),list(返回文件/文件夹的名字),listFiles(返回的是File[])
顶级父类们 | 输入流 | 输出流 |
---|---|---|
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
下面我们分别从输入流和输出流来学习IO流:
输出字节流:OutputStream抽象类,常用方法:close(),flush(),write(byte[] b),write(byte[] b,int off从0开始,int len),write(int)
输入字节流:InputStream抽象类,close(),read()从输入流读取数据的下一个字节,read(byte[])
输出字符流:Writer抽象类,常用方法:close(),flush(),write(int),write(char[]),write(char[] b,int off,int len),write(str)
flush
:刷新缓冲区,流对象可以继续使用。close
:关闭流,释放系统资源。关闭前会刷新缓冲区。输入字符流:Reader抽象类,close(),read(),read(char[])
IO异常处理有两种方式,一种是throw Exception,一种是try...catch...finally
IO流还有缓冲流、转换流、序列化流:
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,等凑够了缓冲区大小的时候一次性写入磁盘,减少系统IO次数,从而提高读写的效率。
BufferedInputStream(InputStream),BufferedOutputStream(OutputStream),BufferedReader(Reader),BufferedWriter(Writer),其中bufferedReader.readLine()有特有方法读取一行文字,bufferedReader.newLine()写出行分隔符(换行),试试使用缓冲流赋值一个大文件;
字符集了解一下:ASCII字符集,GBK字符集(GBK编码),Unicode字符集(utf-8编码,utf-16编码,utf-32编码)
转换流只是字符流来说的因为字节流不会出现乱码问题:InputStreamReader(InputStream),InputStreamReader(InputStream,"GBK"),OutputStreamWriter(OutputStream),OutputStreamWriter(OutputStream,"utf8"),读取GBK编码的文件通过转换流输出未utf8编码的文件。
使用序列化流的对象需要满足两个条件:首先必须实现 java.io.Serializable
接口,类的属性不能被transient
关键字修饰(serialVersionUID序列化的版本号 表示序列化版本标识符的变量),序列化流ObjectOutputStream(OutputStream),常用方法writeObject(Object)将指定的对象写出。
反序列化流ObjectInputStream(InputStream),readObject()返回Object,如果能找到一个对象的class文件,我们可以使用readObject()进行反序列化操作。
打印流PrintStream,其实我们常用的PrintStream out = System.out
,打印流中有我们常用的print(),println()方法,PrintStream(String filename)输出到filename中,使用System.setOut(out)可以改变System.out.println()的输出流向;
内存操作流:
ByteArrayInputStream、ByteArrayOutputStream
CharArrayReader、CharArrayWriter
输出(ByteArrayInputStream):程序 → ByteArrayInputStream→ 内存;
输入(ByteArrayOutputStream):程序 ← ByteArrayOutputStream← 内存;
// IO流部分必会写的内容
char[] chars = new char[1024];
int len;
while ((len = fis.read(chars))!= -1){
fos.write(chars,0,len);
}
Java NIO和IO的主要区别:
Java NIO系统的核心在于:
缓冲区:
Buffer(IntBuffer,ByteBUffer) 主要用于与NIO 通道进行交互
,数据是从通道读入缓冲区,从缓冲区写入通道中的。标记、位置、限制、容量遵守以下不变式: 0 <= mark <= position <= limit后数据不能进行读写 <= capacity
通道Channel:
表示IO 源与目标打开的连接
。Channel接口--(FileChannel,DatagramChannel,SocketChannel,ServerSocketChannel)在 JDK 1.7 中的 NIO.2 增加XXXChannel.open()创建Channel,通过(RandomAccessFile、Socket、ServerSocket、DatagramSocket)FileInputStream.getChannel()也可以获取通道。传统的IO 流都是阻塞式的。
也就是说,当一个线程调用read() 或write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务。服务器端需要处理大量客户端时,性能急剧下降。
Java NIO 是非阻塞模式的。
当线程从某通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。线程通常将非阻塞IO 的空闲时间用于在其他通道上执行IO 操作,所以单独的线程可以管理多个输入和输出通道。 channel.configureBlocking(false);开启非阻塞模式
选择器(Selector)是SelectableChannle 对象的多路复用器,Selector 可以同时监控多个SelectableChannel 的IO 状况,也就是说,利用Selector可使一个单独的线程管理多个Channel。Selector 是非阻塞IO 的核心。SelectableChannle -->-->SocketChannel,ServerSocketChannel,DatagramChannel
Selector.open() 方法创建一个Selector。向选择器注册通道:SelectableChannel.register(Selector sel,int ops);
当调用register(Selector sel, int ops) 将通道注册选择器时,选择器对通道的监听事件,需要通过第二个参数ops 指定SelectionKey.OP_READ...。
Java NIO 管道是2个线程之间的单向数据连接。 Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。
NIO2-->new Paths.get()-->new Path(),Files工具类,JDK7新特性:自动资源管理(Automatic Resource Management, ARM),该特性以try 语句的扩展版为基础。
并发和并行的概念,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为线程调度。
进程和线程的概念,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程,是系统运行程序的基本单位,一个进程可以同时并发的运行多个线程
继承Thread重写run(线程执行体)方法,每一个执行线程都有一片自己所属的栈内存空间(联系JVM的虚拟机栈)Thread(),Thread(name),Thread(Runable,[name]),Thread(target)常用方法:getName()获取现场名称,start()--虚拟机调用该现场的run()方法,sleep(),currentThread()返回当前线程对象。
创建线程的三种方式:extends Thread(),实现Runable接口重写run()——适合多个相同的程序代码的线程去共享同一个资源,Thread(new FutureTask(Callable的子类——重写call()方法))
Java线程分为:守护线程,用户线程,Java垃圾回收就是一个典型的守护线程。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。
Java线程同步机制:
对于非static方法,同步锁就是this。
对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。
java.util.concurrent.locks.Lock 机制提供了比synchronized更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。lock()加同步锁,unlock()释放同步锁。
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁,产生死锁的四个必要条件:
线程创建之后它将处于 NEW(新建) 状态,调用 start() 方法后开始运行,线程这时候处于 READY(可运行)状态。可运行状态的线程获得了 cpu 时间片后就处于 RUNNING(运行) 状态。
线程间通信——等待唤醒机制:线程A生产包子,线程B吃包子。wait方法与notify方法必须要由同一个锁对象调用,notifyAll()释放所通知对象的 wait set 上的全部线程。
线程池的好处:减低资源消耗,提高响应速度,提高线程的可管理性。
线程池接口是 java.util.concurrent.ExecutorService
。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在java.util.concurrent.Executors
线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。官方建议使用Executors工程类来创建线程池对象。
Executors类中有个创建线程池的方法如下:
Executors.newCachedThreadPool():
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
Executors.newFixedThreadPool(n); 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
Executors.newSingleThreadExecutor()
:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
Executors.newScheduledThreadPool(n)
:创建一个定长线程池,支持定时及周期性任务执行。
阿里规约里面为什么线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险说明:Executors各个方法的弊端:
newFixedThreadPool和newSingleThreadExecutor:主要问题是推积的请求处理队列可能会耗费非常大的内存,甚至OOM)
newCachedThreadPool和newScheduledThreadPool:主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
线程池有哪些参数,各代表什么意思?线程池中提供哪些队列种类和拒绝策略呢?
corePollSize:
核心线程数。在创建了线程池后,线程中没有任何线程,等到有任务到来时才创建线程去执行任务。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
maximumPoolSize
:最大线程数。表明线程中最多能够创建的线程数量。
keepAliveTime
:空闲的线程保留的时间。
TimeUnit
:keepAliveTime参数的时间单位
BlockingQueue
:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选。
ThreadFactory
:线程工厂,用来创建线程
RejectedExecutionHandler
:队列已满,而且任务量大于最大线程的异常处理策略。
怎么使用线程池呢?ExecutorService.submit(new Runable(){重写run方法})从线程池中获取线程对象,然后调用MyRunnable中的run()
ExecutorService.shutdown()关闭线程池。
类之间的关系: 依赖(我中有你你就是依赖我)、继承(空心实线)、实现(空心虚线)、关联(特殊的依赖)、聚合(空心菱形,整体与部分之前的关系,可分)与组合(不可分)。
单一职责原则
接口隔离原则
依赖倒转(倒置)原则
:抽象不应该依赖细节,细节应该依赖抽象里氏替换原则
:开闭原则
:一个软件实体类,模块和函数应该 对扩展开放( 对提供方),对 修改关闭( 对使用方)。用抽象构建框架,用实现扩展细节。迪米特法则
:一个对象应该对其他对象保持最少的了解合成复用原则
:原则是尽量使用合成/聚合的方式,而不是使用继承。切面只是一个带有@Aspect注解的Java类
,它往往要包含很多通知。切入点表达式:==execution(访问权限符 返回值类型 方法全类名(参数表))==
@Before
:前置通知,在方法执行之前执行@After
:后置通知,在方法执行之后执行@AfterRunning
:返回通知,在方法返回结果之后执行@AfterThrowing
:异常通知,在方法抛出异常之后执行@Around
:环绕通知,围绕着方法执行execution(* *.*(..))
") public void myPoint(){ } --> @Before(value = "myPoint()")JoinPoint
的子接口,调用proceed()
方法来执行被代理的方法。execution(public int cn.justweb.calculator.impl.CalculatorImpl.add(int,int))
execution(* *.*(..))
千万别写,了解一下正常执行:环绕通知 -- @Before前置通知 -- 方法执行 -- 环绕通知 -- @After后置通知 -- @AfterReturning正常返回
异常执行:环绕通知 -- @Before前置通知 -- @After后置通知 -- @AfterThrowing方法异常
正常执行:环绕通知 -- @Before前置通知 -- 方法执行 -- @AfterReturning正常返回 -- @After后置通知 -- 环绕通知
异常执行:环绕通知 -- @Before前置通知 -- @AfterThrowing方法异常 -- @After后置通知
单例模式的应用:Runtime类(饿汉式),Spring的FactoryBean
饿汉式:静态对象初始化,静态方法返回对象,私有化的构造器
懒汉模式:静态对象定义但是不初始化,在静态方法中判断对象是否为null,来创建对象并返回,私有化构造器。(该模式多线程下不安全,可以给方法添加synchronized )
双重检查☆线程安全; 延迟加载; 效率较高:volatile(保证内存可见性--JMM,防止指令重排) 声明对象
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
静态内部类:在静态内部类中声明静态对象,定义同步的静态方法返回对象实例(类装载的机制来保证初始化实例时只有一个线程)
建立连接的代价是比较昂贵的
,因为我们频繁的创建关闭连接,是比较耗费资源的,我们有必要建立数据库连接池
,以提高访问的性能。
主从复制
,实现读写分离,使增删改操作走主节点,查询操作走从节点,从而可以降低单台服务器的读写压力。命中
了缓存,则立即返回存储在缓存中的结果。否则进入下一阶段;MySQL的主从复制, 就是通过该binlog实现的。
默认是关闭的,需要手动开启mysqlbin.000001Reset Master 指令删除全部 binlog 日志
,删除之后,日志编号,将从 xxxx.000001重新开始 。purge master logs to 'mysqlbin.******'
,该命令将删除 ******
编号之前的所有日志。purge master logs before 'yyyy-mm-dd hh24:mi:ss'
,该命令将删除日志为 "yyyy-mm-dd hh24:mi:ss" 之前产生的所有日志 。
Master 主库在事务提交时,会把数据变更作为时间 Events 记录在二进制日志文件 Binlog 中。
主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。
slave重做中继日志中的事件,将改变反映它自己的数据。
主库出现问题,可以快速切换到从库提供服务。
可以在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力。
可以在从库中执行备份,以避免备份期间影响主库的服务。
oracle.jdbc.OracleDriver
jdbc:oracle:thin:@IP:1521:orcl
关系型数据库和非关系型数据库有什么区别?
Redis是以key-value的形式存储的非关系型数据库,分布式的,开源的,水平可扩展的,为了保证效率,数据都是缓存在内存中,它也可以周期性的把更新的数据写入磁盘或把修改操作写入追加的记录文件中。
Redis支持的五种数据类型:字符串类型String,哈希类型hash,列表类型lisst,集合类型set,有序集合类型sortedset
Redis持久化方式RDB(默认-定时快照方式)和AOP(基于语句追加文件的方式)的区别:
Redis可以通过 maxmemory 参数来限制最大可用内存,主要为了避免Redis内存超过操作系统内存,从而导致服务器响应变慢甚至死机的情况。
//使用Redis有哪些好处?
a.单线程,利用redis队列技术并将访问变为串行访问,消除了传统数据库串行控制的开销
b.redis具有快速和持久化的特征,速度快,因为数据存在内存中。
c.分布式 读写分离模式
d.支持丰富数据类型
e.支持事务,操作都是原子性,所谓原子性就是对数据的更改要么全部执行,要不全部不执行。
f.可用于缓存,消息,按key设置过期时间,过期后自动删除
//缺点:缓存与数据库双写不一致,缓存雪崩,缓存穿透
懂得JVM内部的内存结构、工作机制,是设计高扩展性应用和诊断运行时问题的基础,也是Java工程师进阶的必备能力。
JVM字节码包含了Java虚拟机指令集(或者称为字节码、Bytecodes)和符号表,还有一些其他辅助信息。
虚拟机可以分为系统虚拟机和程序虚拟机:典型代表就是Java虚拟机
,Java技术的核心就是Java虚拟机(JVM) ,因为所有的Java程序都运行在Java虚拟机内部。
HotSpot VM是目前市面上高性能虚拟机的代表作之一。
它采用解释器与即时编译器并存
的架构。
Java编译器输入的指令流基本上是一种基于栈的指令集架构
,特点:指令集更小,编译器容易实现。不需要硬件支持,可移植性更好,更好实现跨平台。
了解JVM的发展历程:Classic VM(只有解释器,JDK1.4被淘汰)-->Exact VM(准确式内存管理,编译与解释混合工作)-->HotSpot VM
(JDk1.3开始,具有热点代码探测技术) -->JRockit VM(JDK89中整合到HostspotVM中)-->J9-->Taobao JVM(基于openJDK HotSpot VM发布的国内第一个优化、深度定制且开源的高性能服务器版Java虚拟机。创新的GCIH (GC invisible heap)技术实现了off-heap ,即将生命周期较长的Java对象从heap中移到heap之外,并且GC不能管理GCIH内部的Java对象,以此达到降低GC的回收频率和提升Gc的回收效率的目的,但是硬件严重依赖intel的cpu。)
字节码文件:-->类加载器子系统(加载,链接[验证,准备,解析],初始化)-->运行时数据区(方法区,堆空间,栈空间,PC寄存器,本地方法栈)-->执行引擎(解释器,JIT即时编译器)
类变量
分配内存并且设置该类变量的默认初始值,即零值。这里不包含用final修饰的static,因为final在编译的时候就会分配了,准备阶段会显式初始化;
<clinit>()
的过程:☆javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。☆只有类变量才有方法。我们把大厨后面的东西(切好的菜,刀,调料),比作是运行时数据区。而厨师可以类比于执行引擎。
线程私有(程序计数器,虚拟机栈[栈帧(局部变量表,操作栈,动态链接,方法返回地址)],本地方法栈;
线程间共享:堆、堆外内存(永久代或元空间[常量池,方法元信息,类源信息]、代码缓存)
在Hotspot JVM里,每个线程都与操作系统的本地线程直接映射。
JVM系统线程:虚拟机线程,周期任务线程,GC线程,编译线程,信号调度线程。
程序计数器作用:
虚拟机栈(通过-Xss1m设置栈空间大小):栈帧的大小主要由局部变量表和操作数栈决定的。
该对象引用this将会存放在index为0的变量槽Slot处,
其余的参数按照参数表顺序继续排列。栈顶缓存(Tos,Top-of-Stack Cashing)技术
,将栈顶元素全部缓存在物理CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率。在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(symbolic Reference)保存在class文件的常量池里。
在Hotspot JVM中,直接将本地方法栈和虚拟机栈合二为一。
“几乎”所有的对象实例以及数组都应当在运行时分配在堆上。堆在逻辑上JDK1.7(新生代,老年代,永久代),JDK1.8(新生代,老年代,元空间)
通常会将-Xms(memory start)和-Xmx两个参数配置相同的值,其目的是为了能够在Java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能。
初始内存大小:物理电脑内存大小/64;
最大内存大小:物理电脑内存大小/4;
年轻代(Eden:Survivor0:Survivor):老年代=1(8:1:1):2
,from区、to区,复制之后有交换,谁空谁是to。。
当发现在整个项目中,生命周期长的对象偏多,那么就可以通过调整 老年代的大小,来进行调优。
几乎所有的Java对象都是在Eden区被new出来的。
绝大部分的Java对象的销毁都在新生代进行了。(有些大的对象在Eden区无法存储时候,将直接进入老年代)
IBM公司的专门研究表明,新生代中80%的对象都是“朝生夕死”的。
当老年代内存不足时,再次触发GC:Major GC
,进行老年代的内存清理。若老年代执行了Major GC之后,发现依然无法进行对象的保存,就会产生OOM异常
如果Survivor区满了后,不会触发MinorGC操作,将会触发一些特殊的规则
,也就是可能直接晋升老年代
当年轻代空间不足时,就会触发Minor GC
出现了Major GC,经常会伴随至少一次的Minor GC,如果Major GC后,内存还不足,就报OOM了。
由Eden区、survivor space0(From Space)区向survivor space1(To Space)区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。
会触发Full GC
70%-99%的对象是临时对象。
分代的唯一理由就是优化GC性能
大对象直接分配到老年代,因为如果在from/to间来回复制消耗性能。
TLAB
,也就是为每个线程单独分配了一个缓冲区。
仅占有整个Eden空间的1%
JDK6 Update 24之后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,否则将进行Full GC。
如果经过逃逸分析(Escape Analysis)后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。
逃逸分析的基本行为就是分析对象动态作用域
:
当一个对象在方法中被定义后,对象只在方法内部使用,则认为没有发生逃逸,则可以在栈上分配。
Person(方法区) person(Java栈) = new Person()Java堆;方法区主要存放的是 Class,而堆中主要存放的是实例化的对象。
在jdk7及以前,习惯上把方法区,称为永久代。jdk8开始,使用元空间取代了永久代,并且元空间存放在堆外内存中。
,使用永久代容易出现OOM,因为永久代的空间大小不好配置。元空间使用本地内存。
内存泄漏就是 有大量的引用指向某些对象,但是这些对象以后不会使用了,但是因为它们还和GC ROOT
有关联,所以导致以后这些对象也不会被回收,这就是内存泄漏的问题。
可进一步通过工具查看泄漏对象到GC Roots的引用链。
于是就能找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。
掌握了泄漏对象的类型信息,以及GC Roots引用链的信息
,就可以比较准确地定位出泄漏代码的位置。方法区:它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。
JDK1.6及以前 | 有永久代,静态变量存储在永久代上 |
---|---|
JDK1.7 | 有永久代,但已经逐步 “去永久代”,字符串常量池,静态变量移除,保存在堆中 |
JDK1.8 | 无永久代 ,类型信息,字段,方法,常量保存在本地内存的元空间,但字符串常量池、静态变量仍然在堆中。 |
明白Web,网页,网站,Web前端,后端,Html(超文本标记语言),CSS(层叠样式表),JavaScript(直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。),TypeScript,浏览器内核,字符集(编码解码)等概念;
<!--首先要有文档头DOCTYPE,指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。-->
<!DOCTYPE html>
<!--html根标签,head头部,body主体内容-->
<html lang="en"><!--lang="zh-cn"-->
<head>
<meta charset="UTF-8">
<title>网页的标签</title>
<stype>
</stype>
</head>
<body>
<a href="http://www.itbuild.cn">超链接(默认是_self)...</a>
<a href="http://www.itbuild.cn" target="_blank">超链接...</a><!--在新页面中打开-->
<a href="http://www.itbuild.cn" targe="_self">超链接...</a>
<p>段落标签1</p>
<p>段落标签2</p>
<h1>标题标签h1</h1>
<h6>标题标签h6</h6>
<h7>标题标签h7(正常文本)</h7>
<div>div双标签</div>
<font color="blue">字体标签</font>
<textarea cols="4" rows="4">文本域标签</textarea>
<strong><b>加粗的新老标签</b></strong>
<em><i>倾斜新老标签</i></em>
<ins><u>下划线新老标签</u></ins>
<del><s>删除新老标签</s></del>
<!--但标签:hr红头线,br换行-->
<hr>
<br>
<img src="/aaa/bbb/ccc.jpg">
<!--列表-->
<ul>
<li>无序列表</li>
<li>无序列表</li>
</ul>
<ol>
<li>有序列表</li>
<li>有序列表</li>
</ol>
<dl>
<!--dl中只能是dt和dd,是一个可描述的列表-->
<dt>dt</dt>
<dd>dd</dd>
</dl>
<table border="1px" width="100%">
<caption>表格的标题</caption>
<thead><!--定义表格的头部,必须要有tr-->
<!--表格标签-->
<!--td thd的属性
rowspan=“x” x表示跨行数
colspan=“y” y表示跨列数
-->
<tr>
<th>表头1</th>
<th>表头2</th>
</tr>
</thead>
<tbody>
<!--一行两列-->
<tr>
<td>a</td>
<td>b</td>
</tr>
</tbody>
</table>
<!--表单form-->
<form action="http://www.itbuild.cn" method="POST" name="表单名称">
<!--value 默认显示的文本-->
<!--type 属性 可以决定了你属于那种input表单-->
<!--name表单的名字, 这样,后台可以通过这个name属性找到这个表单。 页面中的表单很多,name主要作用就是用于区别不同的表单。-->
<input type="text" value="单行文本输入框" name="duanduan">
<input type="password" value="密码输入框">
<input type="radio" value="单选按钮" checked="checked">
<input type="checkbox" value="复选框">
<input type="button" value="普通按钮">
<input type="submit" value="提交按钮">
<input type="reset" value="重置按钮">
<input type="image" value="图像形成按钮">
<input type="file" value="文件域">
<!--lable标签用于绑定一个表单元素, 当点击label标签的时候, 被绑定的表单元素就会获得输入焦点。-->
<label> 用户名:<input type="radio" name="usename" value="请输入用户名"> </label>
<textarea name="" id="1" cols="1" rows="1"></textarea>
<!--select下拉列表-->
<select name="" id="2">
<option value="">A</option>
<option value="">B</option>
<option value="">C</option>
<option value="">D</option>
</select>
</form>
</body>
</html>
表格的属性:
border-collapse:collapse;
相邻边框合并在一起。块级元素(div,h1-h6,hr,p,ul,li,ol,li,dl,dt,dd),行内元素(span,strong,del,ins,em,a),行内块级元素。
特殊字符:空格
了解CSS的三种书写方式:
<div style="color: red; font-size: 12px;">青春不常在,抓紧谈恋爱</div>
<style>div{color: red;}</style>
<link rel="stylesheet" type="text/css" href="css文件路径">
CSS选择器:有标签选择器div,类选择器.类名
(一个标签可以设置多个类属性,使用空格分隔),id选择器#id
(元素的id值是唯一的,只能对应于文档中某一个具体的元素),通配符选择器*
。
.class h3
,子元素选择器.class>h3
,链接的伪类选择器(a:link a:visited a:hover a:active)
lvha 的顺序不可变。元素+相邻兄弟元素;
元素~后面所有兄弟元素;
元素1,元素2;
li[title='ddaimm']
为title='ddaimm'属性的元素设置样式。~=
包含,^=
以这个值开头,$=
以这个为结尾,*=
包含值得所有元素。li:first-child{}
选择li标签父元素的第一个孩子元素,如果该元素是li标签,那么触发下面的样式。li:last-child{}
选择li标签父元素的最后一个孩子元素,如果该元素是li标签,那么触发下面的样式。li:nth-child(3)
,从1开始
li:first-of-type,li:last-of-type
li:nth-of-type(3)
匹配属于父元素的特定类型的第n个子元素
ul :not(span)
前面有空格,指的是ul标签下面的所有子标签。通过CSS设置字体的样式:font-size: 16px/1em;
,font-family:“微软雅黑”;
开发中可以使用unicode编码设置字体,font-weight: normal/bold/400/700;
,font-style: normal/italic;
选择器 { font: font-style font-weight font-size/sline-height font-family;}
,不能更换顺序,但必须保留font-size和font-family属性。文本水平对齐方式color: red/#90ee90/rgb/rgba;
,文本水平对齐方式text-align: left/right/center;
,行间距line-height: 16px/2em;
,首行缩进text-ident: em;
,文本的修饰text-decoration: none/underline/overline/line-through;
元素模式 | 元素排列 | 设置样式 | 默认宽度 | 包含 |
---|---|---|---|---|
块级元素 |
一行只能放一个块级元素 | 可以设置宽度高度 | 容器的100% | 容器级可以包含任何标签 |
行内元素 |
一行可以放多个行内元素 | 不可以直接设置宽度高度 | 它本身内容的宽度 | 容纳文本或则其他行内元素 |
行内块元素 |
一行放多个行内块元素 | 可以设置宽度和高度 | 它本身内容的宽度 |
CSS背景的设置:background-color: #90ee90;
,background-image: none/url;
url(多个url使用,分隔)不加引号,background-repeat: repeat/no-repeat/repeat-x/repeat-y;
背景平铺,background-position: x|y(top/right/bottom/left/center);
背景位置需要基于背景位置,background-attachment: scroll/fixed;
背景附着;
background: transparent url(image.jpg) repeat-y scroll center top ;
background: rgba(0,0,0,0.3);
==背景==透明。background-size:cover/contain;
设置图片大小,cover默认查找最远边,contain默认查找最近边。行高line-height: x%/ypx;
,基线和基线的距离;
CSS三大特性:层叠性(长江后浪推前浪,前浪死在沙滩上),继承性(子承父业),优先级(谁的权重大,谁生效);
继承的权重是 | 0 |
---|---|
标签选择器的权重是/元素选择器 | 1 |
类选择器的权重是 | 10 |
id选择器的权重是 | 100 |
行内样式的权重是 | 1000 |
!important 权重是 | 无穷大 |
盒子模型有元素的内容、边框(border)、内边距(padding)、和外边距(margin)组成。
border: 1px solid/dashed/dotted/none red;
,还可以使用border-top/border-top-stype;
padding: 上% 右px 下% 左px;
(一个值就是上右下左),如果没有给一个盒子指定宽度, 此时,如果给这个盒子指定padding, 则不会撑开盒子,相反如果设置了宽高盒子会被撑大。也可以使用padding: 上下内边距 左右内边距;
,padding-left: 16px;
盒子的实际的大小 = 内容的宽度和高度 + 内边距 + 边框。
块级盒子水平居中:一、设置盒子的宽高;二、左右外边距设置atuo。盒子内的文字水平居中是text-align: center;
, 而且还可以让行内元素和行内块居中对齐。
盒子模型布局稳定性:优先使用 宽度 (width) 其次 使用内边距(padding)再次 外边距(margin)
。
扩展:
list-style:none;
border-radius: 16px/50%;
box-shadow: 5px 5px 3px 4px rgba(0, 0, 0, .4);
box-shadow:水平阴影 垂直阴影 模糊距离(虚实) 阴影尺寸(影子大小) 阴影颜色 内/外阴影;
盒子浮动float:
float:left/right/none;
是指设置了浮动属性的元素
会:脱离标准普通流的控制,移动到指定位置。浮动只会影响当前的或者是后面的标准流盒子,不会影响前面的标准流。
clear:left/right/both;
主要为了解决父级元素因为子级浮动引起内部高度为0 的问题。清除浮动之后, 父级就会根据浮动的子盒子自动检测高度。父级有了高度,就不会影响下面的标准流了
<div style="clear:both"></div>
,或则其他标签br等亦可。overflow:hidden/auto/scroll;
属性方法。就是内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。定位:将盒子定在某一个位置 自由的漂浮在其他盒子(包括标准流和浮动)的上面 。
定位 = 定位模式 + 边偏移
position:static/relative/absolute/fixed;
静态/相对/绝对/固定定位。
相对定位
是元素相对
于它原来在标准流中的位置来说的。原来在标准流的区域继续占有,后面的盒子仍然以标准流的方式对待它。绝对定位
是元素以带有定位的父级元素来移动位置,完全脱标 —— 完全不占位置,父元素没有定位,则以浏览器为准定位(Document 文档)。
子绝父相
—— 子级
是绝对
定位,父级
要用相对
定位,因为==父级要占有位置,子级要任意摆放==。固定定位
是绝对定位
的一种特殊形式,完全脱标,只认浏览器的可视窗口
—— 浏览器可视窗口 + 边偏移属性
来设置元素的位置。position:absolute;left:50%;margin-left:-weigthpx;
z-index
层叠等级属性可以调整盒子的堆叠顺序
,正整数
、负整数
或 0
,默认值是 0,数值越大,盒子越靠上;z-index
只能应用于相对定位
、绝对定位
和固定定位
的元素。box-sizing: content-box/border-box;
默认是content-box
伪元素:div::first-line第一行,div::first-letter第一个字母,div::before,div::after在元素的内容前/后面插入新内容,常与content配合使用,div::selection用于设置浏览器中选中文本后的背景色与前景色。
边框圆角(块元素,行内块元素,行内元素):border-radius:%/px;
,一个值4个角都生效。可以制作八卦图,大风车。
文字阴影text-shadow,可以实现文字阴影,浮雕文字,文字描边,文字排版等。
/*text-shadow: 水平方向的偏移量,垂直方向的偏移量,模糊程度,阴影的颜色。*/
text-shadow:6px -6px 2px lightgreen,7px -7px 1px lightpink;
/*字间距*/
letter-spacing: 10px;
/*描边*/
-webkit-text-stroke: 4px deeppink;
/*文字方向:ltr/rtl*/
direction:rtl;
盒子阴影:box-shadow,可以实现立体球等效果。
/* box-shadow:水平方向的偏移量,垂直方向的偏移量,模糊程度,扩展程度,盒子阴影的颜色,inset 内阴影*/
box-shadow:5px -5px 10px 10px rgba(88,255,99,1) inset;
/*不设置inset为外阴影,为一个盒子设置多给阴影使用“,”隔开*/
/*box-reflect : 倒影的方向(above below left right ) 倒影与元素之间的距离 倒影效果(线性渐变)*/
-webkit-box-reflect:below 10px linear-gradient(0deg,rgba(0,0,0,1),rgba(0,0,0,0));
/*横向拉动长短*/
resize:horizontal;
/*纵向拉动长短*/
resize:vertical;
/*拉动横向和纵向长短*/
resize:both;
背景模糊(图片文字都可以)filter:blur(5px);
渐变gradient:
background-image:linear-gradient(方向,颜色,颜色);
background: linear-gradient(red 10%,blue 20%,green 30%,yellow 40%);
background:linear-gradient(to right,red 25%, blue 25%, blue 50%,green 50%, green 75%, yellow 75%);
background:radial-gradient(circle/ellipse,颜色,颜色);
过度transition: property duration timing-function delay;
时间顺序不能乱,其他参数位置不限,如果想给多个属性添加不同的过度,参数之间使用逗号分开。
transition-property: none/all/property;
transition-duration: 2s/2000ms;
transition-delay: 2s/2000ms;
变换transform:
transform: rotate(45deg);
如果是正数,顺时针旋转,如果是负数,逆时针旋转。transform: translate(xpx,ypx)/translateX(xpx)/translateY(ypx);
transform: scale(0.5,2)/scale(0.5)/scale(2);
transform: skew(xdeg,ydwg)/skew(xdeg)/skew(ydeg);
transform-style: preserve-3d;
,一般对父元素设置。
perspective: 300px;
实现元素在3D空间中的近大远小的效果,景深值越大,效果越不明显,越接近2d变换。50% 50% 0
,Z轴只能使用具体的长度。perspective-origin: top right;
改变观察者视角backface-visibility: visible/hidden;
(默认值:可见)动画animation:@keyframes animation-name{0%{}100%{}};
,结合着变换和精灵图可以实现很多有意思的动画。
animation-name: 动画名称;
animation-duration: 5s;
动画持续时间animation-timing-function:
动画的过渡类型,处理可以设置一下内容还可以使用steps(x);
animation-delay:2s;
动画的延迟时间animation-iteration-count:infinite;
动画循环次数animation-direction:normal/reverse/alternate/alternate-reverse;
animation-play-state:paused/running;
动画运行的状态animation-fill-mode:backwards/forwards/both;
设置对象动画外的状态animation: name duration timing-function delay interation-count direction play-state;
伸缩盒子模型flex:flex布局原理就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式。开启flex布局:display: flex;
flex-direction: row/row-reverse/column/column-reverse;
设置flex布局的主轴;justify-content: flex-start/flex-end/center/space-around/space-between;
设置主轴上的子元素的排列方式;flex-wrap:nowrap/wrap;
子元素是否换行,默认不换行;align-items: flex-start/flex-end/center/stretch;
设置侧轴上的子元素的排列方式(只能在子元素单行时设置);align-content: flex-start/flex-end/center/space-around/space-between/stretch;
设置侧轴上的子元素的排列方式(只能在子元素多行时设置)flex-flow: flex-direction flex-wrap;f
lex主轴金和子元素是否换行的复合属性;flex: 2;
flex属性定义子项目分配剩余空间,用flex来表示占多少份数默认是0;align-self: flex-start/flex-end/center;
控制子项自己在侧轴上的排列方式;order: -1;
属性定义项目的排列顺序,数值越小,排列越靠前,默认为0。语义化标签布局:
多媒体:
Canvas
什么是JS:一种直译式解释脚本语言
,动态类型、弱类型、基于原型的语言,内置支持类型。
JS的组成:ECMA,BOM,DOM
声明变量使用:var、val、let;变量命名同Java,Python声明变量直接写。在JS中使用var定义的变量,会存在变量提升。
JS数据类型:number,string.length,boolean,==object==,undefined,Symbol,Null
JS运算符和赋值运算符同Java,JS特有的比较运算符 ==等于 ===等值类型 != !==
,注意for循环中的声明变量,声明数组var arr = [1,2,3,4,"hahah"]
,数组的遍历arr.length,JS也支持面向对象。
常用函数parseInt(),console.log(),typeof(),instanceof(),document.write()
// 自定义函数
function haha(param1,param2){
/*方法体;*/
return xxx;
}
// 匿名函数
var haha = function(param1,param2){}()
JSON(JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JS常用对象:
var zhangsan={"name":"张三","age":19,"sex":"男"}
明白JDBC整个流程,软件架构C/S和B/S结构的区别,以及静态资源和动态资源的概念,还有网络通信的三要素:
传输协议:规定了数据传输的规则。
ip地址:电子设备(计算机)的在网络中的唯一标识。
端口号:应用程序在电子设备(计算机)中的位置标识。
明白web服务器(安装了服务器软件的计算机),web服务器软件(接收用户的请求,处理请求,响应结果)的概念。常见的web服务器软件有:tomcat中小型,weblogic大型,websphere大型,JBoss大型。
tomcat和nginx的区别:
servlet接口,定义了Java类如何能够被浏览器访问到的规范。自定义类(servlet对象在第一次被访问到的时候创建,load-on-startup>=0时tomcat启动时创建)实现servlet接口重写
Servlet3.0(WEB3.0)算是比较新的Servlet技术了,对应版本JDK7,Servlet3.0的配置步骤:定义一个servlet类,实现servlet接口,重写方法,使用注解配置(可以省略web.xml不写):
@WebServlet(urlPatterns = {"/student","/student1"},loadOnStartup = 1)
@WebServlet("/mm")
public class HelloServlet implements Servlet{
//重写Servlet方法
}
大数据技术之Spark生态圈
git clone https://gitee.com/duanchaojie/java-code.git
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。