2020-11-15

1.接口和抽象类的区别

1.相同点
A. 两者都是抽象类,都不能实例化。
B. interface实现类及abstract class的子类都必须要实现已经声明的抽象方法。
2. 不同点
A. interface需要实现,要用implements,而abstract class需要继承,要用extends。
B. 一个类可以实现多个interface,但一个类只能继承一个abstract class。
C. interface强调特定功能的实现,而abstract class强调所属关系。
D. 尽管interface实现类及abstract class的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的 (declaration, 没有方法体),实现类必须要实现。而abstract class的子类可以有选择地实现。

2.类的加载顺序

public class LoadingSequence {
    public static void main(String[] args) {
        System.out.println(BX.c);
    }
}
class AX{
    static {
        System.out.println("A");
    }
}
class BX extends AX{
    static {
        System.out.println("B");
    }
    public static final String c = "C";
}

这道题的运行结果是C,如果将final去掉结果是ABC,原因就是使用final修饰的常量在程序编译时期就将常量C放入了常量池,而调用常量c不需要将类初始化,所以就不需要加载static代码块,这就是为什么将final去掉之后才是ABC的原因。

什么是常量?常量是用final修饰的成员变量!常量在类编译时期载入类的常量池中。

静态代码块的加载顺序:父类的静态代码块>子类的静态代码块>父类非静态代码块>父类构造方法>子类非静态代码块>子类构造方法

3.HashMap的底层结构

总之就是一句话:HashMap的底层通过位桶实现,位桶里面存的是链表(1.7以前)或者红黑树(有序,1.8开始) ,其实就是数组加链表(或者红黑树)的格式,通过判断hashCode定位位桶中的下标,通过equals定位目标值在链表中的位置,所以如果你使用的key使用可变类(非final修饰的类),那么你在自定义hashCode和equals的时候一定要注意要满足:如果两个对象equals那么一定要hashCode相同,如果是hashCode相同的话不一定要求equals!所以一般来说不要自定义hashCode和equals,推荐使用不可变类对象做key,比如Integer、String等等

4.什么反射

Java 反射,就是在运行状态中。
1.获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
2.获取任意对象的属性,并且能改变对象的属性
3.调用任意对象的方法
4.判断任意一个对象所属的类
5.实例化任意一个类的对象

Java 的动态就体现在这。通过反射我们可以实现动态装配,降低代码的耦合度;动态代理等。反射的过度使用会严重消耗系统资源

5.如何保证线程的安全

一、线程安全在三个方面体现
1.原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized);
2.可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile);
3.有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序,(happens-before原则)

线程安全的定义
当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的。

所有如何保证线程安全:周武回答。

6.怎么防止SQL注入攻击

1.通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
2.找到SQL注入的位置
3.判断服务器类型和后台数据库类型
4.针对不同服务器和数据库的特点进行SQL注入攻击
方法:
1.检查用户输入变量的数据类型和格式
2.过滤特殊的符号
3.绑定变量,使用预编译语句

7.JDBC的实现过程

1、加载驱动程序
Class.forName(DriverClass);
2、使用驱动管理类,获得数据库连接
Connection conn = DriverManager.getConnection(URL,USER,PASSWORD);
URL格式: jdbc:数据库类型://IP地址:端口号/数据库名
示例 URL= “jdbc:mysql://127.0.0.1:3306/student”
3、使用数据库连接创建声明
Statement stmt = conn.createStatement();
4、使用声明执行SQL语句
ResultSet rs = stmt.executeQuery(“sql”);
5、遍历集合,读取数据
boolean b = rs.next();
rs.getString();

8.Redis如何缓存项目

Redis在项目中的应用场景
1、缓存数据
最常用,对经常需要查询且变动不是很频繁的数据 常称作热点数据。
2、消息队列
相当于消息订阅系统,比如ActiveMQ、RocketMQ。如果对数据有较高一致性要求时,还是建议使用MQ)
3、计数器
比如统计点击率、点赞率,redis具有原子性,可以避免并发问题
4、电商网站信息
大型电商平台初始化页面数据的缓存。比如去哪儿网购买机票的时候首页的价格和你点进去的价格会有差异。
5、热点数据
比如新闻网站实时热点、微博热搜等,需要频繁更新。总数据量比较大的时候直接从数据库查询会影响性能
随着企业的发展、业务的扩展。面对海量的数据,直接使用MySql会导致性能下降,数据的读写也会非常慢。于是我们就可以搭配缓存来处理海量数据。
缓存的作用,当数据继续增大我们需要利用主从复制技术来达到读写分离
数据库层直接与缓存进行交互,如果缓存中有数据直接返回客户端,如果没有才会从MySql中去查询。从而减小了数据库的压力,提升了效率。

9.Mybatis如何实现分页
使用Limit实现分页

#语法
SELECT * FROM table LIMIT stratIndex,pageSize

SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15  

#为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:   
SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.  

#如果只给定一个参数,它表示返回最大的记录行数目:   
SELECT * FROM table LIMIT 5; //检索前 5 个记录行  

#换句话说,LIMIT n 等价于 LIMIT 0,n

步骤:
1、修改Mapper文件

<select id="getUserByLimit" resultMap="Usermap" parameterType="map">
        select id,name,pwd from user limit #{startIndex},#{pageSize};
    </select>

2、Mapper接口,参数为map

List<user>  getUserByLimit(Map<String,Object> map);

3、在测试类中传入参数测试

@Test
    public void getUserByLimit(){
        SqlSession sqlSession=MybatisUtils.getSqlSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        Map<String,Object> map= new HashMap<String, Object>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<user> users=userMapper.getUserByLimit(map);
        for (user us:users){
            System.out.println(us);
        }

}

10.jdk1.8的新特性

*1. Lambda表达式
2.函数式接口
3.方法引用和构造器调用
4.Stream API
5.接口中的默认方法和静态方法
6.新时间日期API

11.数据库的隔离级别

1,读未提交,Read Uncommited
指的是一个事务读取到另外一个事务还没有提交的内容。这种情况是必须要避免的。因为其他事务未提交的数据,是随时有可能进行回滚的,所以,任何时候,都不应该允许程序读取到某个事务还未提交的数据。如果读取到了别的事务未提交的数据,这种情况称为脏读。要想解决脏读的问题,可以提高数据库的事务隔离级别,把事务隔离级别设置为读已提交。

2,读已提交,Read Committed
这个隔离级别可以解决脏读的问题。
在该隔离级别下,不允许2个未提交的事务之间并行执行,但它允许在一个事务执行的过程中,另外一个事务得到执行并提交。这样,会出现一种情况,第一个事务前后两次select出来的某行数据,值可能不一样。值改变的原因是,穿插执行的事务2对该行数据进行了update操作。在同一个事务中,两次select出来的值不相同的问题称为不可重复读问题。要想解决不可重复读问题,需要把数据的隔离级别设置为可重复读。

3,可重复读。Repeatable Read
在这个隔离级别下,可以解决不可重复读的问题。
在该隔离级别下,在一个事务使用某行的数据的过程中,不允许别的事务再对该行数据进行操作。可重复读是给数据库的行加上了锁。这种隔离级别下,依旧允许别的事务在该表中插入和删除数据,于是就会出现,在事务1执行的过程中,如果先后两次select出符合某个条件的行,如果在这两次select之间另一个事务得到了执行,insert或delete了某些行,就会出现先后两次select出来的符合同一个条件的结果不一样,第一次select好像出现了幻觉一样,因此,这个问题也被成为幻读。要想解决幻读问题,需要将数据库的隔离级别设置为串行化。

4, 串行化,Serialization
串行化可以解决幻读的问题。
它要求事务的执行完全串行执行。所以失去了并发的效率。
Mysql的默认隔离级别为可重复读。
总结而言,数据的事务隔离级别分为4种,从低到高依次为读未提交,读已提交,可重复读,串行化。与数据库事务隔离级别相关的问题有3个,分别是脏读,不可重复读,幻读。脏读问题需要用读已提交来解决,但读已提交会存在不可重复读问题。不可重复读问题需要用可重复读来解决,但可重复读会存在幻读问题。幻读问题需要用串行化来解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值