策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
Java多线程编程核心技术
Java多线程技能
进程和多线程的概念和线程的优点
进程
是操作系统, 是一次程序的执行; 是一个程序及其数据在处理机上依此执行时所发生的活动;是程序在一个数据集合上运行的过程,他是系统进行资源分配和调度的一个独立单位。
线程
是进程中独立运行的子任务。
线程的优点:增加cpu利用率
使用多线程
使用Thread类
使用Runnable接口
实例变量与共享安全
留意i--
与System.out.println()
的异常
concurrentThread()
方法
isAlive()
方法
sleep()
方法
getId()
方法
对象及变量的并发访问
线程间通信
线程之间通过合适的方法通信,从单纯的抢夺关系,变成协作更强的团队作战
By Watson
使用wait/notify实现线程间通信
通过管道进行线程通信
方法join的使用
ThreadLocal类的使用
Lock的使用
定时器Timer
单例模式与多线程
to be continued…
自定义注解的场景及实现
自定义注解使用场景
- 类属性自动赋值
- 验证对象属性完整性
- 代替配置文件功能(例如spring基于注解的配置)
- 可以生成文档(例如javadoc的@see@param)
自定义注解的实现
注解是插入到源码中使用其他工具可以对其进行处理的标签
下面是一个简单注解的实例
1
2
3
4public class MyClass{
...
@Test pulbic void checkRandomInsertions()
}
在java中,注解是当作一个修饰符来使用的,它被置于注解项之前,中间没有分号;注解是代码的一部分
@Test 注解本身并不会做任何事情,它需要工具支持才会有用。例如,当测试一个类的时候,JUnit4 测试工具可能会调用所有标识为@Test 的方法。另一个工具可能会删除一个类文件的所有测试方法,以便在对这个类测试完毕后,不会将这些测试方法和程序装载在一起。
注解可以定义成包含元素的形式,例如:1
@Test(timeout= "10000")
每个注解都必须通过一个注解接口进行定义。这些接口中的方法与注解中的元素相对应。例如,Junit 的注解Test可以用下面这个接口进行定义:1
2
3
4
5@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{
long timeout() default OL;
}
@interface声明创建了一个真正的java接口。处理注解的工具将接收那些实现了这个注解接口的对象。这类工具可以调用timeout方法来检索某个特定Test注解的timeout元素。
注解Target和Retention是元注解。他们注解了Test注解,即将Test注解标识成一个只能运用到方法上的注解,并且当类文件载入到虚拟机的时候,依然可以保留下来。
注解语法
注解接口
注解是由注解接口来定义的1
2
3
4modifiers @interface AnnotationName{
elementDeclaration1;
elementDeclaration2;
}
每个元素声明都具有下面这种形式:1
type elementName();
或者1
type elementName() default value;
注解元素的类型为下列之一:
- 基本类型(int、short、long、byte、char、double、float或者boolean)
- String
- Class(具有一个可选的类型参数,例如Class<? extends MyClass>)
- enum类型
- 注解类型
- 由前面所述类型组成的数组(由数组组成的数组不是合法的元素类型)
下面是一个合法的元素声明的例子:1
2
3
4
5
6
7
8
9public @interface BugReport{
enum Status { UNCONFIRMED, CONFIRMED, FIXED, NOTABUG};
boolean showStopper() default false;
String assignedTo() default "[none]";
Class<?> testCase() default Void.class;
Status status() default Status.UNCONFIRMED;
Reference ref() default @Reference;//an annotation type
String[] reprotedBy();
}
注解
每个注解都具有下面这种格式:1
@AnnotationName(elementName1=value1, elementName2=value2, ...)
例如,1
@BugReport(assignedTo="Harry", severity=10)
元素的顺序无关紧要。下面这个注解和前面那个一样1
@BugReport(severity=10, assignedTo="Harry")
如果某个元素的值并未指定,那么就使用声明的默认值。例如,考虑一下下面这个注解1
@BugReport(severity=10)
元素assignedTo的值是字符串”[none]”
有两个特殊的快捷方式可以用来简化注解。
如果没有指定元素,要么是因为注解中没有任何元素,要么是因为所有的元素都使用默认值,那么你就不需要用圆括号了。例如,1
@BugReport
这样的注解也称为标记注解;
另一种快捷方式是单值注解。如果一个元素具有特殊的名字value,并且没有指定其他元素,那么你就可以忽略掉这个元素名以及等号。例如:1
2
3public @interface ActionListenerFor{
String value();
}
可以将注解书写成如下格式:1
@ActionListenerFor("yellow")
而不是1
@ActionListenerFor(value="yellow")
注解各类声明
注解可以出现在许多地方,这些地方可以分为两类:声明和类型用法。声明注解可以出现在下列声明出:
- 包
- 类(包括enum)
- 接口(包括注解接口)
- 方法
- 构造器
- 实例域(包含enum常量)
- 局部变量
- 参数变量
- 类型参数
注解类型用法
声明注解提供了正在被声明的项的相关信息。例如,在下面的声明中1
public User getUser(@NonNull String userId)
就断言userId参数不为空
类型用法注解可以出现在下面的位置:
- 与泛化类型引元一起使用
- 数组中的任何位置
- 与超类和实现接口一起使用
与构造器调用一起使用:
1
new @Localized String(...)
与强制转型和instanceof检查一起使用
1
(@Localized String)text, if(text instanceof @Localized String)
与异常规约一起使用
- 与通配符和类型边界一起使用
- 与方法和构造器引用一起使用
注解this
了解一下1
2
3public class Point{
public boolean equals(@ReadOnly Point this, @ReadOnly Object other){...}
}
第一个参数被称为接收器参数,它必须被命名为this,而它的类型就是要构建的类。
标准注解
注解接口 | 应用场合 | 目的 |
---|---|---|
Deprecated | 全部 | 将项标记为过时 |
SuppressWarnings | 除了包和注解之外的所有情况 | 阻止某个给定类型的警告信息 |
SafeVarargs | 方法和构造器 | 断言varargs参数可安全使用 |
Override | 方法 | 检查该方法是否覆盖了某一个超类方法 |
FunctionalInterface | 接口 | 将接口标记为只有一个抽象方法的函数式接口 |
PostConstruct | 方法 | 被标记的方法应该在构造之后立即被调用 |
PreDestroy | 方法 | 被标记的方法应该在移除之前立即被调用 |
Resource | 类、接口、方法、域 | 在类或接口上:标记为在其他地方要用到的资源。在方法或域上:为“注入”而标记 |
Resources | 类、接口 | 一个资源组 |
Generated | 全部 | |
Target | 注解 | 指明可以应用这个注解的那些项 |
Retention | 注解 | 指明这个注解可以保留多久 |
Documented | 注解 | 指明这个注解应该包含在注解项的文档中 |
Inherited | 注解 | 指明当这个注解应用与一个类的时候,能够自动被它的子类继承 |
Repeatable | 注解 | 指明这个注解可以在同一个项上应用多次 |
用于编译的注解
用于管理资源的注解
元注解
源码级注解处理
注解处理
1 | javac -process ProcessorClassName1, ProcessorClassName2, ...sourceFiles |
语言模型API
使用注解来生成源码
to be continued…
Java面试题一
基础篇
Java基础
- 面向对象的特征:继承、封装和多态
- final、finally和finallize的区别
- Exception、Error、运行时异常与一般异常有何异同
- 请写出5种常见的RuntimeException
- int和Integer有什么区别,Integer的值缓存范围
- 包装类、装箱和拆箱
- String、StringBuilder、StringBuffer
- 重载和重写
- 抽象类和接口有什么区别
- 说说反射的用途及实现
- 说说自定义注解的场景及实现
- HTTP请求的GET和POST方式的区别
特征 | GET方法 | POST方法 |
---|---|---|
提交数据类型 | 文本 | 文本、二进制文件 |
提交数据长度 | 不超过255个字符 | 没有限制 |
提交数据可见性 | 作为URL地址的一部分显示在浏览器地址栏 | 作为请求的消息体,不可见 |
提交数据缓存 | 缓存在浏览器URL历史状态中 | 不会被浏览器缓存 |
- Session和Cookie的区别
- 列出自己常用的JDK包
- MVC设计思想
- equals与==的区别
- hashCode和equals方法的区别与练习
- 什么是Java序列化和反序列化,如何实现Java序列化?或者请解释Serializable接口的作用
- Object类常见的方法,为什么wait()、notify()会放在Object里边?
- Java的平台无关性如何体现出来的
- JDK和JRE的区别
- Java8有哪些新特性
Java常见集合
- List、Set和Map的区别
- Set和hashCode以及equals方法的联系
- ArrayList和LinkedList的区别
- ArrayList和Vector的区别
- HashMap和HashTable的区别
- HashMap和CurrentHashMap的区别
- HashMap的工作原理及代码实现,什么时候用到红黑树
- 多线程情况下HashMap死循环的问题
- HashMap出现Hash Dos攻击的问题
- ConcurrentHashMap的工作原理及代码实现,如何统计所有的元素个数
- 手写简单的HashMap
- 看过哪些Java集合类的源码
进程和线程
- 线程和进程的概念、并行和并发的概念
- 创建线程的方式及实现
- 进程间通信的方式
- 说说CountDownLatch、CyclicBarrier原理和区别
- 说说Semaphore原理
- 说说Exchanger原理
- ThreadLocal原理分析,ThreadLocal为什么会出现OOM,出现的深层次原理
to be continued…
Mysql语法总结
创建数据库
1 | create database database_name; |
删除数据库
1 | drop database database_name; |
选择数据库
1 | use database_name; |
Mysql数据类型
数值类型
type | Byte | usage |
---|---|---|
tinyint | 1 | 小整数值 |
smallint | 2 | 大整数值 |
mediumint | 3 | 大整数值 |
int或integer | 4 | 大整数值 |
bigint | 8 | 极大整数值 |
float | 4 | 单精度浮点型 |
double | 8 | 双精度浮点型 |
decimal | 对decimal(m,d),为max(m,d)+2 | 要求精度的小数值 |
日期和时间类型
字符串类型
二进制类型
type | Byte | usage |
---|---|---|
binary(n) | n | 较短的二进制数 |
varbinary(n) | 实际占用的字节数 | 较长的二进制数 |
bit(n) | n | 短二进制数 |
tinyblob | 实际占用的字节数 | 较短的二进制数 |
blob | 实际占用的字节数 | 图片、声音等文件 |
mediumblob | 实际占用的字节数 | 图片、声音、视频等文件 |
longblob | 实际占用的字节数 | 图片、声音、视频等文件 |
创建数据表
1 | create table table_name(column_name column_type); |
示例:1
2
3
4
5
6create table if not exists example_table(
example_id int unsigned auto_increment,
example_title varchar(100) not null,
example_date date,
primary key(example_id)
) engine=innodb default charset=utf8 ;
删除数据表
1 | drop table table_name; |
插入数据
1 | insert into table_name |
查询语句
1 | select column_name, column_name from table_name |
where子句
1 | select column_name, column_name from table_name |
分页语句
N代表每页显示row的数量,M代表偏移量,M =(当前第几页 - 1)* N
update语句
1 | update table_name set field1=new_value1, field2=new_value2 ... |
delete语句
1 | delete from table_name [where clause]; |
truncate delete drop比较
1 | -- 删除该表所有row,不会在日志中记录删除内容,效率较高, |