分享Java笔试记录(一)
1. 数据库四大特性:原子性、一致性、隔离性、持久性
原子性:事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功必须要完全应用到数据库,如果操 作失败则不能对数据库有任何影响。
一致性:事务必须使数据库从一个 一致性状态换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务操作所干扰,多个并发事务之间要相互隔离
持久性:一个事务一旦被提交了,那么对数据库中的数据就是永久的,即便是在数据库系统遇到故障的情况也不会丢失提交事务的操作。
2. 抛出异常的关键字:throw、throws
3. drop、delete和truncate的区别
对DDL和DML简要了解
DDL(数据定义语言,Data Definition Language):DDL代表数据定义语言,是一种有助于创建数据库模式的SQL命令。DDL中常用命令有:create,drop,alter,truncate和rename
DML(数据操作语言,Data Manipulation Language):DML代表数据操作语言,是一种有助于检索和管理关系数据库中数据的语言,insert,update、delete和 select
- delete : delete属于数据操作语言、只删除数据不删除结构、会走事务,可以使用where指定删除满足条件的数据,不使用则删除表中所有记录;删除操作记录在redo和undo表空间,InnoDB不删除数据,实质是隐藏,插入数据会重用->覆盖部分空间,可以使用optimize table释放磁盘空间。
- drop : 属于DDL,删除表结构和数据,隐式提交,不能回滚,不会触发触发器,drop删除时会释放空间,表结构所依赖的约束随之删除,触发器、索引、依赖于该表的存储过程/函数保留,但变为invlid状态。
- truncate : 属于DDL,作用是清空表或截断表,会重置auto_increment(自增键)的值(例如id重置为1),只能作用于表,和delete不使用where相似(不会重置自增键),不能回滚,也不会触发触发器、磁盘会随之释放,表结构报错不变,类似drop表再create表
此处引用其他博主的详细解析:drop、truncate和delete的区别及效率
drop>truncate>delete
4. Java 写一个单例模式
理解:单例模式的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点、单例模式包含的角色只有一个,就是单例类—Singleton。单例类拥有一个私有构造函数,确保用户无法通过new实例化它,该模式包含一个静态私有成员变量和静态公有工厂方法,工厂方法负责检验实例的存在性和实例化自己,然后存储到静态成员变量中,以确保只有一个实例被创建
单例模式主要三种:懒汉式单例(线程不安全)、饿汉式单例(线程安全)、登记式单例
此处引用其他博主的详细解析:JAVA设计模式之单例模式
//懒汉式单例,在调用时才实例化自己,可使用同步锁保证线程安全
public class Singleton{
//静态私有成员变量
private static Singleton instance = null;
//私有构造函数
private Singleton(){}
//静态公有工厂方法
public static Singleton getInstance(){
if(instance == null){
instance == new Singleton()
}
return instance
}
}
//饿汉式单例,类初始化时就自行实例化
public class Singleton{
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
5. 用Java写一个合并排序
理解合并排序(归并排序),采用的思想是分治算法
此处引用b站博主的解析:推荐看这位博主解释
递归处理数组的左右部分图解
合并数组左右部分图解
整体算法实现
package studtJava;
public class mergeSort {
public void merge_Sort(int[] a,int left,int right){
if(left>=right) {
return;
}else {
int mid = (left+right)/2;
//递归处理左部分
merge_Sort(a,left,mid);
//递归处理右部分
merge_Sort(a,mid+1,right);
//合并
merge(a,left,right);
}
}
public void merge(int[] a,int left,int right){
int m = right-left+1,left0 = left;
int[] b = new int[m];
int i=0;
int mid = (right+left)/2;
int k=mid+1;
//数组左右部分已经排好序,所以每次挑左/右最小的元素,既是每次遍历的最小值
while ((left<=mid)&&(k<=right)){
if(a[left] < a[k]){
b[i++] = a[left++];
}else {
b[i++] = a[k++];
}
}
//说明左侧有余
if(left>mid){
for(;k<=right;k++){
b[i++]=a[k];
}
}
//说明右侧有余
if(k>right){
for(;left<=mid;){
b[i++]=a[left++];
}
}
//将排序好的b赋值给a
for (int j = 0;j<m;j++){
//这里注意,a数组不一定从0开始
a[left0++] = b[j];
}
}
public static void main(String[] args) {
mergeSort mergeSort = new mergeSort();
int[] a = new int[]{9,5,1,4,8};
int left = 0;
int right = 4;
mergeSort.merge_Sort(a,left,right);
for(int b:a){
System.out.println(b);
}
}
}
//结果 1 4 5 8 9
-
给图写sql语句
SELECT year, SUM ( CASE WHEN month = 1 THEN amount ELSE 0 END ) AS m1, SUM ( CASE WHEN month = 2 THEN amount ELSE 0 END ) AS m2, SUM ( CASE WHEN month = 3 THEN amount ELSE 0 END ) AS m3, SUM ( CASE WHEN month = 4 THEN amount ELSE 0 END ) AS m4 FROM statistic GROUP BY year 或者使用if SELECT year, SUM ( if (month='1',amount,0) ) AS m1, SUM ( if (month='2',amount,0) ) AS m2, SUM ( if (month='3',amount,0) ) AS m3, SUM ( if (month='4',amount,0) ) AS m4 FROM statistic GROUP BY year
典型的行转列问题,交叉表查询,行转列的常规做法,group by + sum(if())【或count(if())】
此处引用其他博主的解释:SQL练习-行转列
题外知识:sql 执行顺序
from --> join --> on --> where --> group by —> select后面的普通字段,聚合函数count,sum —> having —> distinct —> order by —> limit
本次分享仅用于交流学习,记录笔试过程所遇到的题,如有无意侵权,请联系删帖。如有错误的地方,欢迎指出修改