阿里云面试总结

从阿里云的面试问题感觉他对数据库的要求比较高

学习到就是收获!!!!!!!!!!!!!!

简单面试流程:

  1. 自我介绍
  2. 项目介绍
  3. 项目开始往外扩展知识点

 

扩展开始 使用mysql数据库是吧?对 那你说一下。。。。。。。。。。。。。。。。。。。

怎么创建一个表?

create table 表名{字段1 类型,字段2 类型}

在建表的时候还要考虑表与表之间的关系,主键外键,三大范式等等。

 

数据库中的时间类型? 精确度?

Date用来存储没有时间的日期 YYYY-MM-DD 精确度为天

Datetime 用来存储日期和时间的日期 YYYY-MM-DD HH:MM:SS 精确到秒

Timestamp 用来存储日期和时间的日期 YYYY-MM-DD HH:MM:SS 精确到秒

Datetime 和 Timestamp的区别?

两者都是存储日期(date年月日)+时间(time时分秒)的存储格式。

对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储查询时,将其又转化为客户端当前时区进行返回。

而对于DATETIME,不做任何改变,基本上是原样输入和输出。

这里需要对数据库中的数据类型进行学习!!!!!!!!!!!!!!!

数据库中的join?。外连接和内连接的区别?

在了解join之前首先理解一下笛卡尔积,从数学的角度 集合A={a,b,c}, 集合B={1,2,3,4},笛卡尔积就是3*4,12条记录C={(a,1),(a,2),(a,3),(a,4),(b,1),(b,2),(b,3),(b,4),(c,1),(c,2),(c,3),(c,4)}这个c集合就是笛卡尔积。从数据库的角度首先我创建了两张表

CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `t_id` int(11) NOT NULL,

  `name` varchar(20) NOT NULL,

  PRIMARY KEY (`id`),

  KEY `t_id` (`t_id`),

  CONSTRAINT `student_ibfk_1` FOREIGN KEY (`t_id`) REFERENCES `teacher` (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;



CREATE TABLE `teacher` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(20) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

并添加了记录

  

使用自然连接去产生笛卡尔积

SELECT * FROM teacher NATURE JOIN student;

 

join是根据两个或多个表的列之间的关系,查询数据 有时为了得到某个表的完整的数据,需要用到join。这里我使用两张表A和B说明。

natural join 自然连接 查询结果为两张表的笛卡尔积

Inner join on 内连接 查询出的数据为A表和B表两张表根据某一列都能匹配的记录。也就是从笛卡尔积中选择出符合ON字句条件成立的记录。

SELECT * FROM teacher t INNER JOIN student s on t.id = s.t_id;

left join on 左外连接  查询到的结果为 左表中的所有记录和右表中的与左表匹配的记录。也就是从笛卡尔积中选出符合ON条件语句的记录和左表中剩余的记录。

SELECT * FROM teacher t LEFT JOIN student s on t.id = s.t_id;

right join on 右外连接 查询到的结果为 右表中的所有记录和左表中的与右表匹配的记录。也就是从笛卡尔积中选出符合ON条件语句的记录和右表中剩余的记录。

SELECT * FROM student s RIGHT JOIN teacher t on t.id = s.t_id;

 

数据库索引 怎么使用索引?? 没答出来确实没使用过 这里还可以问索引的底层实现?

看这篇博客https://blog.csdn.net/IPI715718/article/details/90140997

什么是事务?

事务就是对数据库的一系列操作,这一系列操作被看成一个原子,要么一系列操作全部执行成功,要么都不执行。

事务的隔离级别?

说事务的隔离级别之前首先说一下为什么要有事物的隔离级别?也就是当多个事务操作数据库时容易产生的问题。

多事务容易产生的问题?

脏读:A事务读取了B事务未提交的数据,然后B事务由于某种原因回滚了,这是A事务读取的就是脏数据。

不可重复读:某一事务第一次读取数据和第二次读取同一数据得到的结果不同。产生原因:A事务第一次读取data=1,然后B事务开始操作数据库将data更新为data=2并提交,A事务再一次读取数据发现data=2,两次读取数据不一致。

幻读:幻读是A事务将一个或者多个数据更新为某一个值比如将a=0,b=0,但是还未提交,这时B事务操作了数据将a=1,并且提交,接下来A开始准备提交,却发现a=1,像是出现了幻觉。

为了解决以上幻读,不可重复读,脏读等问题,提出隔离级别,隔离级别简单理解就是怎么处理多个事务之间的互不影响。

隔离级别的分类

read_uncommited(读未提交):允许读取未提交的数据,这种隔离级别个人认为没有任何作用,解决不了脏读,不可重复读和幻读。

read_conmmited(读已提交):只允许读取已经被提交的数据,这种隔离级别可以解决脏读的问题,但是解决不了不可重复读和幻读。

repeatable_read(可重复读):同一个事务两次查询同一数据的到的数据时相同的,能够解决脏读和不可重复读。Mysql数据库默认隔离级别

Serializable(串行化):事务串行化执行,也就是说比如A事务正在操作数据库,在A未执行完毕之前,其他的事务等待,只有A事务执行完毕之后,其他的事务才能执行。

以上四种隔离级别 从上往下隔离级别逐步增强,代价是查询的效率会变低,比如串行化只能一次执行一个事务。

事物的传播特性 事务的传播特性是指当多个事务相遇时,怎么对这些食物管理的一些策略。

传播特性的分类

Propagation_required:如果存在一个事务,就支持并加入该事务,如果不存在事务就开启一个事务。

Propagation_supports:如果存在一个事务,就支持当前事务,如果不存在就非事务执行。

Propagation_mandatory:如果存在一个事务,就支持并加入当前事务,如果没有事务,报异常。

Propagation_requires_new:开启一个新事务,如果有一个事物存在,就挂起当前事物。

Propagation_unsupports:总是非事务执行,如果存在一个事务,就挂起当前事务。

Propagation_never:总是非事务执行,如果存在一个事务,报异常。

 Propagation_nested:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。 

jdbc 怎么操作事务?

1.业务执行之前关闭自动提交conn.setAutoCommit(false);

默认为true 就是自动提交 sql语句都将作为单个事务执行和提交。

设置为false 关闭自动提交 SQL语句将被看成一个事务通过调用方法commit提交或方法rollback回滚。

  1. 将数据库操作的业务逻辑使用try块 包围,执行完毕没有异常,commit
  2. 出现异常在catch块中回滚
public class UserDao {
	
	static {
		try {
			//加载驱动
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 获取连接
	 * @param url
	 * @param username
	 * @param password
	 * @return
	 */
	public static Connection getConnection(String url,String username,String password) {
		Connection conn =  null;
		try {
			conn = DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	/**
	 * 测试
	 */
	public void insert() {
		Connection conn = getConnection("jdbc:mysql://localhost:3306/users", "root", "root");
		try {
			//默认为true sql语句都将作为单个事务执行和提交
			//设置为false 关闭自动提交 SQL语句将被分组通过调用方法commit或方法rollback终止的事务
			conn.setAutoCommit(false);
			PreparedStatement prepareStatement1 = conn.prepareStatement("update teacher SET name = ? where id = ? ");
			prepareStatement1.setString(1, "小明");
			prepareStatement1.setInt(2, 15);
			prepareStatement1.executeUpdate();
			PreparedStatement prepareStatement2 = conn.prepareStatement("delete from teacher where id = ?");
			prepareStatement2.setInt(1, 12);
			prepareStatement2.executeUpdate();
			//没有异常 提交并正常退出
			conn.commit();
		} catch (SQLException e) {
			try {
				//出现异常回滚
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}
	}
}

Spring的ioc和Aop

IOC控制反转:就是将对象的创建销毁的权利交给spring容器,并且spring容器管理对象的生命周期和依赖注入,简单理解就是在某个对象中使用到另一个对象时,不需要手动的去new依赖的对象,而是spring容器从容器中查找对象,然后注入到该对象中。

IOC的实现原理就是 简单工厂模式+java反射+Map,简单叙述就是在web容器启动时,spring容器将类的全限定名传入到工厂方法中,在工厂方法中对类的全限定名进行java反射得到类对象,然后执行类对象的getInstance()方法创建对象,如果对象是单例模式,会将对象放入Map中作为value,全限定名作为key,存入Map,之后的再次需要依赖该对象时,就直接从Map中取对象,然后注入到需要该对象的对象中去。

Aop 面向切面:面向切面是对面向对象的补充,就是将系统的用户业务逻辑与系统业务逻辑进行分离,将系统逻辑封装成一个切面,切面里的每一个方法就是一个增强,在运行的过程中,将切面里面的增强运用于业务逻辑的连接点上之前,之后,异常时等,通过java反射生成代理对象。作用就是实现用户业务和系统业务的解耦,实现对系统业务代码的重用。

spring怎么操作事务? 内部怎么实现的?

spring的管理实务的方式有两种,一种是编程式事务,一种是声明式事务,声明式事务又分为xml方式和注解@Trancational方式。使用spring开发时,需要配置事务管理器并注入数据源,然后开启事务注解。使用Springboot时,在启动类上使用@EnableTrancationnalManager直接即可开启事务。

实现:spring事务的实现需要依赖于数据库的事务支持,还记得jdbc中使用事务,回顾一下

public class JdbcUtil {
    static final String URL = "jdbc:mysql://192.168.110.3:3306/xxxx?useSSL=false&useUnicode=true" +
            "&characterEncoding=UTF-8&serverTimezone=GMT%2B8";
    static final String USERNAME = "root";
    static final String PASSWORD = "root";
    /**
     * 加载驱动
     */
    static {
        try {
            Class.forName("com.mysql.cj.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取jdbc连接
     * @return
     */
    public static Connection getConnection(){
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    public static void main(String[] args) {
        Connection conn = JdbcUtil.getConnection();
        PreparedStatement statement = null;
        try {
            //关闭自动提交 也就是开启了事务
            conn.setAutoCommit(false);
            statement = conn.prepareStatement("update user set name = ? where id = ?");
            statement.setString(1, "张三");
            statement.setInt(2,2);
            statement.executeUpdate();
            //成功提交
            conn.commit();
        } catch (SQLException e) {
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

从中我们可以看到jdbc使用事务时,是关闭了自动提交  conn.setAutoCommit(false);  并且在对数据库的操作成功后手动 conn.commit(); 异常时 conn.rollback(); 回滚,在spring的事务中也是同样的方法,只不过是将关闭自动提交、提交和回滚封装成了增强。

spring操作事务两种 1.xml声明式配置 2.注解配置 (1)开启事务注解(2) 配置事务管理器 使用@trancational

内部怎么实现的?未整理没看过源码

java的类加载机制? 

Java虚拟机将类的class文件加载到内存,并对数据进行检验,解析和初始化,最终形成被Java虚拟机直接使用的Java类型这就是Java的类加载机制。

Java类加载使用到了双亲委派模型,双亲委派模型的过程是这样的,当类加载器接收到类加载的请求时,首先类加载器不会去加载这个类而是查看自己的缓存中有没有加载过此类,有就不再委派,没有就交给父类加载器去加载,父类加载器重复同样的过程,最终委派到启动类加载器(bootstrap classloder),启动类加载器会试着去加载,父类加载器加载不到,就让子类加载器去加载,如果所有的类加载器都加载不到 报java.lang.ClassNotFound异常。

双亲委派模型的好处和优点?

当时我是这么说的,我说是防止类的重复加载,保证了类的唯一性。就是说的不够全面,接着面试官立马又提出了一个问题,从下往上加载也能保证类不重复加载?????当时懵了 回答就是目前没了解那么多,面试过后我会去深思学习这个问题。其实我只答对了一点。比较好的回答是

  1. java类随着它的加载器一起具备了一种带有优先级的层次关系,能够避免类的重复加载,保证类在内存中的唯一性。2. 保护了jdk的核心类库不受影响,例如用户自己定义了一个java.lang.Object,如果不使用双亲委派模型,由非启动类加载器加载了自定义java.lang.Object类,会使核心类库被篡改。

接下来面试官又问道,知不知道什么东西破坏了双亲委派模型??? 不太了解,接着面试官也是在引导我,说你知道tomcat的模型是什么样的吗??NO

tomcat的类加载

 

Synchronized锁是否可重入?

https://www.cnblogs.com/incognitor/p/9894604.html

动态代理?

Jdk和cglib区别

Jdk代理接口,会产生一个兄弟类作为代理类,cglib代理类,会产生一个子类代理类。

代理方法能被重复代理吗?

被代理类能被重复代理吗?

 

Sql注入是什么?怎么防止sql注入?

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。例如 select * from user where password=  and username= 

Sql注入在表单提交时输入 or 1=1# (这里#是mysql数据库的注解)

这时语句为

select * from user where password=  and username=  or 1=1#

其实就是

select * from user where password=  and username=  or 1=1

防止sql注入

1.jdbc 使用preparestatement 设置参数和执行 原理是能预编译sql语句格式能能固定并且参数是使用方法设置进去的,

2.mybatis使用#{}传值 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值