- 1、sleep() 和 wait ()的区别
- 2、instanceof关键字作用
- 3、java反射里,如果创建类的实例,请写出示例
- 4、通过反射获取私有属性,方法和构造方法时,该如何实现?
- 5、简要画一下:数组,栈,队列,链表,图,树,哈希表的数据结构
- 6、Spring框架中都用到了哪些设计模式?并进行举例
- 7、Spring支持bean的几种作用域?
- 8、Spring中的@Qualifier注解有什么作用?
- 9、写一个java冒泡排序算法实现
- 10、写出您所了解的会引起SQL全表扫描的情况
- 11、login_table表有id(主键)、user_id(会员id)、login_time(登录时间)三个字段,每天都有会员登录数据产生,写sql查询所有会员的最新登录时间
- 12、写出你所了解的提高网站并发性能 的手段
1、sleep() 和 wait ()的区别
1、**sleep()**是线程类Thread 方法,**wait() **是Object 方法<br /> 2、**sleep()**让出Cpu(CPU可以去执行其它资源),而不会释放同步资源锁!睡眠时间到线程进入就绪状态和其他线程一起竞争cpu的执行时间。<br /> wait()让出Cpu,并且释放同步锁,未设置超时间(自动解除阻塞)只有调用notify()、notifyAll()方法唤醒,可以去参与竞争同步资源锁,进而得到执行 <br /> 3、**sleep()方法**可以在任何地方使用;**wait()方法**则只能在同步方法或同步块(synchronized块)中使用;
心得2 sleep不释放任务a资源锁,导致其它线程抢不到这个任务a,保证同步性,不需要同步块,睡眠结束自动请求执行时间, 而wait方法释放锁会出现lost wake up问题,其它线程会抢任务a,导致同步混乱,所以需要在同步方法或同步锁中执行
1.1、sleep是Thread方法,wait是 Object方法
1.2、sleep不释放锁,wait是释放锁
sleep()
public class Test {
private final static Object lock = new Object();
public static void main(String[] args) {
Stream.of("线程1","线程2").forEach(n->new Thread(n) {
public void run(){
Test.testSleep();
}
}.start());
}
//sleep方法休眠之后,
private static void testSleep() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName()
+"正在执行");
Thread.sleep(10_000);
System.out.println(Thread.currentThread().getName()
+"休眠结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
线程2先获取了cpu资源,然后开始执行休眠,在休眠过程中线程1是没法执行的,必须要等待线程2结束之后才可以。这也就是说sleep方法不会释放锁,让其他线程进来。
wait()
public class Test {
private final static Object lock = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(n -> new Thread(n) {
public void run() {
Test.testWait();
}
}.start());
}
private static void testWait() {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName()
+ "正在执行");
lock.wait(10_000);
System.out.println(Thread.currentThread().getName()
+ "wait结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
程序结果:
1.3、sleep不依赖同步方法(synchronized),wait需要
测试sleep方法
public class Test2 {
private final static Object lock = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(n -> new Thread(n) {
public void run() {
Test2.testSleep();
}
}.start());
}
private static void testSleep() {
try {
Thread.sleep(10_000);
System.out.println("休眠结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这个方法会依次运行,不会出现任何异常。然后我们主要是看wait方法。
public class Test2 {
private final static Object lock = new Object();
public static void main(String[] args) {
Stream.of("线程1", "线程2").forEach(n -> new Thread(n) {
public void run() {
Test2.testSleep();
}
}.start());
}
private static void testWait() {
try {
lock.wait(10_000);
System.out.println("wait结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
程序结果:
1.4、sleep不需要被唤醒,wait需要
sleep方法很简单,我们主要关注wait方法。看代码:
首先我们定义两个方法,一个等待方法,一个唤醒方法。
public class Test2 {
private final static Object lock = new Object();
private static void testWait() {
synchronized (lock) {
try {
System.out.println("我一直在等待");
lock.wait();
System.out.println("wait被唤醒了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void notifyWait() {
synchronized (lock) {
try {
Thread.sleep(5_000);
lock.notify();
System.out.println("休眠5秒钟唤醒wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试一下:
public class Test2 {
private final static Object lock = new Object();
public static void main(String[] args) {
new Thread() {//这个线程一直在等待
public void run() {
Test2.testWait();
}
}.start();
new Thread() {//这个线程准备去唤醒
public void run() {
Test2.notifyWait();
}
}.start();
}
}
程序结果:
如果没有唤醒方法,那第一个线程就会处于一直等待的状态,第二个线程唤醒了之后就不再等待了。
2、instanceof关键字作用
instanceof 运算符是用来在运行时判断对象是否是指定类及其父类的一个实例。
比较的是对象,不能比较基本类型 即它左边的对象是否是它右边的类的实例
package constxiong.interview;
/**
* 测试 instanceof
* @author xxk
* @date 2019-10-23 11:05:21
*/
public class TestInstanceof {
public static void main(String[] args) {
A a = new A();
AA aa = new AA();
AAA aaa = new AAA();
System.out.println(a instanceof A); //true
System.out.println(a instanceof AA); //false
System.out.println(aa instanceof AAA); //false
System.out.println(aaa instanceof A); //true
}
}
class A {
}
class AA extends A {
}
class AAA extends AA {
}
3、java反射里,如果创建类的实例,请写出示例
1)通过类的对象,获取类对象
Person person = new Person();
Class cla = person.getClass();
场景:常用于对象的字节码获取方式
2)通过类名获取类对象
Class cla = 类名.class;
场景:常用于参数的传递
3)以静态方法通过全类名获取类对象
Class cla = Class.forName("全类名");
场景:常用于读取配置文件,将类名定义在配置文件中。读取文件,加载类对象。
4、通过反射获取私有属性,方法和构造方法时,该如何实现?
1.获取Class对象
1.Class userClass = User.class;
2.Class.forName(com.dsm.domain.User);
3.User user = new User();
user.getClass();
2.获取所有的构造方法
Constructor[] constructors = userClass.getDeclaredConstructors();
//遍历构造方法
Arrays.stream(constructors).forEach(System.out::println);
3.获取指定的构造方法
Constructor constructor = null;
try {
constructor = userClass.getDeclaredConstructor(String.class);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(constructor);
4.创建对象
//开启暴力访问
constructor.setAccessible(true);
User user = null;
try {
user = (User)constructor.newInstance("董世铭");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印创建的对象
System.out.println(user);
5.获取类的所有私有方法
Method [] methods = userClass.getDeclaredMethods();
Arrays.stream(methods).forEach(System.out::println);
6.获取所有的私有属性
Field[] fields = userClass.getDeclaredFields();
Arrays.stream(fields).forEach(System.out::println);
7.生成get和set方法
PropertyDescriptor pd = null;
try {
pd = new PropertyDescriptor(fields[0].getName(),User.class);
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//生成get方法
Method method = pd.getReadMethod();
8.调用方法
try {
System.out.println(method.invoke(user));
} catch (Exception e) {
e.printStackTrace();
}
5、简要画一下:数组,栈,队列,链表,图,树,哈希表的数据结构
6、Spring框架中都用到了哪些设计模式?并进行举例
简单工厂模式: BeanFactory 或 ApplicationContext 创建 bean 对象。
工厂方法模式:Spring中的FactoryBean就是典型的工厂方法模式。
单例模式:Spring提供了全局的访问点BeanFactory。
适配器模式:Spring中在对于AOP的处理中有Adapter模式,由于Advisor链需要的是MethodInterceptor(拦截器)对象,所以每一个Advisor中的Advice都要适配成对应的MethodInterceptor对象。
装饰模式:Spring中用到的装饰模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。
代理模式:Spring的Proxy模式在aop中有体现。
观察者模式:Spring中Observer模式常用的地方是listener的实现。
策略模式:Spring中在实例化对象的时候用到Strategy模式。
模板方法模式:用来解决代码重复的问题。比如. RestTemplate, JdbcTemplate。
7、Spring支持bean的几种作用域?
singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例
prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例
request:对于每次 HTTP 请求,使用 request 定义的 bean 都将产生一个新实例,即每次 HTTP 请求将会产生不同的 bean 实例。
session:同一个 Session 共享一个 bean 实例。
global-session:同 session 作用域不同的是,所有的Session共享一个Bean实例。
8、Spring中的@Qualifier注解有什么作用?
@Qualifier 注解来指定应该装配哪个具体的Bean
如在控制层注入 service 而service的实现类有2个 到底使用哪个呢
9、写一个java冒泡排序算法实现
public class Demo {
public static void Bubble_sort(int[] list) {
int length = list.length;
// length 个元素,遍历 length-1 次
for (int i = 0; i < length-1; i++) {
// 从第 1 个元素开始遍历,遍历至 length-1-i
for (int j = 0; j < length - 1 - i; j++) {
// 比较 list[j] 和 list[j++] 的大小
if (list[j] > list[j + 1]) {
// 交换 2 个元素的位置
int temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
}
public static void main(String[] args) {
int[] list = { 14, 33, 27, 35, 10 };
Bubble_sort(list);
// 输出已排好序的序列
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
}
}
10、写出您所了解的会引起SQL全表扫描的情况
- 模糊查询like 全表扫描
- 查询条件中含有is null的select语句执行慢
- 查询条件中使用了不等于操作符(<>、!=)的select语句执行慢
- or语句使用不当会引起全表扫描
- select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。
11、login_table表有id(主键)、user_id(会员id)、login_time(登录时间)三个字段,每天都有会员登录数据产生,写sql查询所有会员的最新登录时间
select user_id from login_table order by login_time desc
12、写出你所了解的提高网站并发性能 的手段
1、使用缓存 redis
2、消息队列 mq
3、数据库分库分表
4、采用集群 多服务器
5、采用分布式 再用nginx负载均衡