面试问答题汇总

1.抽象类为什么不能创建对象?

1.子类更具体,父类更抽象,直接创建父类对象本身没有意义。

2.如果创建的是父类对象,在调用方法的时候,调用的父类中的方法而并非子类的方法,他违背了多态的设计思想。

3.因为父类引用指向子类对象时,调用的方法是子类重写的方法,并不是说抽象类的构造方法没有意义,那么在创建子类对象时需要先调用父类的构造方法。

(1)抽象类的定义:
      抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。通常在编译语句中用abstract修饰的类是抽象类。

在c++中,含有纯虚拟函数的类称为抽象类,它不能创建对象;在java中,含有抽象方法的类称为抽象类,它同样也不能创建对象。

(2)抽象方法(由子类具体实现)

java中的抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型,方法名称和所需的参数,没有返回方法体,也就是抽象方法只需要声明而不需要实现。抽象方法不能被调用。

(3)抽象类为什么不能创建对象?

首先,与具体的类进行比较:抽象类不能实例化,并且不能使用new创建对象(如果使用,会导致编译时错误)。虽然一些变量和值在编译时的类型可以为抽象的,但是,这些变量和值必须为null,或者说含有对非抽象类的实例的引用(此非抽象类是从抽象类派生出来的),允许抽象类包含抽象成员。

其次,与接口进行比较:

相同点:(1)抽象类和接口都不能直接实例化(创建对象);

               (2)抽象类的子类(或接口的实现类),都必须实现抽象类(或接口)中全部的抽象方法,才可以被实例化,否                 则,该类仍然为抽象类

不同点:(1)关键字不同,抽象类子类使用extends关键字实现抽象类;接口实现是使用关键字implements来实现接口

              (2)抽象类中可以有构造方法;接口中不能有构造方法

              (3)抽象类中既可以有抽象方法也可以有普通方法;接口中只能有抽象方法

              (4)权限修饰不同:抽象方法可以有public,protected和default这些修饰符;接口方法只能是public

              (5)抽象类中的变量可以是普通变量;接口中定义的变量只能是公共的静态变量

              (6)抽象方法可以继承单个类和实现多个接口;接口可以多继承接口

              (7)速度:抽象类比接口的速度要快,接口稍微有点慢,需要时间去寻找在类中实现的方法

 

补充::

注意:

(1)一个类中如果有抽象方法,那么这个类只能是抽象类

(2)抽象方法要被实现,所以不能是静态的,也不能是私有的

(3)接口中只能含有未被实现的方法,也叫抽象方法;但是不能用abstract关键字修饰

抽象类的使用原则:

(1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public; 
(2)抽象类不能直接实例化,需要依靠子类采用向上转型的方式处理; 
(3)抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类; 
(4)子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法(如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。);

抽象类是不能定义对象的。一个纯虚函数不需要(但是可以)被定义。

2.SQL查询语句关键字的执行顺序

Mysql语法顺序:

  1. select[distinct]  
  2. from  
  3. join(如left join)  
  4. on  
  5. where  
  6. group by  
  7. having  
  8. union  
  9. order by  
  10. limit  

Mysql执行顺序

  1. from  
  2. on  
  3. join  
  4. where  
  5. group by  
  6. having  
  7. select  
  8. distinct  
  9. union  
  10. order by  


3.Statement和PreparedStatement的区别

(1)什么是Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。

(2)Statement对象用于将SQL语句发送到数据库中,用于执行静态 SQL 语句并返回它所生成结果的对象。

实际上有Statement有三种对象,Statement它们都作为在给定连接上执行SQL语句的包容器:

Statement,PreparedStatement(它是由Statement上继承来的),CallableStatement(它从PreparedStatement继承来的)。

它们都专用于发送特定类型的SQL语句:

  • Statement对象用于执行不带参数的简单SQL语句;
  • PreparedStatement对象用于执行带或不带参数的预编译的SQL语句;
  • CallableStatement对象用于执行对数据库已存储过程的调用。

(3)PreparedStatement: 表示预编译的 SQL 语句的对象,SQL 语句被预编译并存储在 PreparedStatement 对象中。

数据库会对sql语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率(但尽量采用使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用。 从安全性上来看,PreparedStatement是通过?来传递参数的,避免了因sql而出现sql注入的问题,所以安全性较好。 在开发中,推荐使用 PreparedStatement

优劣比较:

Statement每次执行sql语句,数据库都要执行sql语句的编译,最好用于仅执行一次查询并返回结果的情形,效率高于  PreparedStatement.但存在sql注入风险。

PreparedStatement是预编译执行的。在执行可变参数的一条SQL时,PreparedStatement要比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率高。安全性更好,有效防止SQL注入的问题;有更好的可读性和可维护性;对于多次重复执行的语句,使用PreparedStatement效率会更高一点。

4.lock 和 synchronized

  • synchronized 是 Java 关键字,内置特性;Lock 是一个接口
  • synchronized 会自动释放锁;lock 需要手动释放,所以需要写到 try catch 块中并在 finally 中释放锁
  • synchronized 无法中断等待锁;lock 可以中断
  • Lock 可以提高多个线程进行读/写操作的效率
  • 竞争资源激烈时,lock 的性能会明显的优于 synchronized

可重入锁

  • 定义:已经获取到锁后,再次调用同步代码块/尝试获取锁时不必重新去申请锁,可以直接执行相关代码
  • ReentrantLock 和 synchronized 都是可重入锁

公平锁

  • 定义:等待时间最久的线程会优先获得锁
  • 非公平锁无法保证哪个线程获取到锁,synchronized 就是非公平锁
  • ReentrantLock 默认时非公平锁,可以设置为公平锁

乐观锁和悲观锁

乐观锁与悲观锁是逻辑上的锁。

乐观锁:

  • 乐观锁:乐观地认为,并发问题很难发生。
  • 乐观锁虽然认为并发问题很难发生,但并不是不会发生,所以也会有措施防止问题真的产生:每次数据修改都自增版本号version。
  • 进行数据读取时,并不加锁,而是同时读取当前的版本号version1;在对数据进行修改时,要判断当前的版本号version2是否等于之前的版本号version1。
  • 版本号不匹配,则代表着并发问题已产生,所以需要回滚此次操作。
  • 实现方式:版本号机制、CAS。Compare And Swap,更新数据时先比较原值是否相等,不相等则表示数据过去,不进行数据更新

悲观锁:

  • 悲观锁:悲观地认为,并发问题极易发生。synchronized 就是悲观锁
  • 悲观锁认为并发问题极易发生,所以每次操作,无论读写,都会对记录加锁,以防止其他线程对数据进行修改。
  • 实现方式:数据库的行锁、读锁和写锁

行级锁和表级锁

行级锁

  • ow-level loking,锁住一行记录。
  • 开销大,加锁慢。
  • 会死锁。
  • 锁粒度小,发生所冲突概率小,并发效率高。
  • 适合并发写,事务控制。
  • 并不是直接丢记录行加锁,而是对行对应的索引加锁:

如果sql 语句操作了主键索引,Mysql 就会锁定这条主键索引。
如果sql语句操作了非主键索引,MySQL会先锁定该非主键索引,再锁定相关的主键索引。
在InnoDB中,如果SQL语句不涉及索引,则会通过隐藏的聚簇索引来对记录加锁。
对聚簇索引加锁,实际效果跟表锁一样,因为找到某一条记录就得扫描全表,要扫描全表,就得锁定表。

表级锁

  • table-level locking,锁住整个表。
  • 开销小,加锁快。
  • 不会死锁(一次性加载所需的所有表)。
  • 锁粒度大,发生锁冲突概率大,并发效率低。
  • 适合查询。

共享锁与排他锁


共享锁:

  • 有称之为S锁、读锁。
  • 当前线程对共享资源加共享锁,其他线程可以读取此资源、可以继续追加共享锁,但是不能修改此资源、不能追加排他锁。
  • 语法:select id from t_table in share mode;
  • 多个共享锁可以共存,共享锁与排他锁不能共存。

排他锁:

  • 又称之为X锁、写锁。
  • 当前线程对共享资源加排他锁,其他线程不允许读取此资源,不允许追加共享锁,不允许修改此资源,不允许追加排他锁。

       语法:

       update t_table set a =1; // 数据库的增删改操作默认都会加排他锁
       select * from t_table for update;// for update也是一种增删改

  • 排他锁是独占的,不会与其他锁共存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值