java面试主要提问总结一

1、封装、继承、多态

继承:基于某个父类扩展出一个新的子类,子类可以继承父类原有的属性和方法,也可以增加父类中不具备的属性和方法,或者直接重写父类中的某些方法。
封装:将对象的属性和行为封装起来,对客户隐藏其实现细节。保证了类内部数据结构的完整性。
多态:多态使程序具有良好的扩展性,程序可以对所有的类进行通用的处理。一个接口,多种实现是多态的体现,或者父类的引用变量可以指向子类的实例。多态可分为两种类型:编译时多态(方法的重载)和运行时多态(继承时方法的重写)。

2、数据库索引的原理

聚集索引
如果给表添加了主键,表中数据存储的结构由排列结构变为树状结构(平衡树),整个表变成了一个索引,也就是聚集索引。
假如表中有1万条数据,如果按照常规去匹配,最坏情况下要匹配1万次才能得到结果,对查询性能有非常大的提升。
如果将表转换成平衡树,假设树有10层,则只需要10次IO开销即可查到所需数据。
索引能让查询速度提升,但是会使写入速度下降。平衡树要维持正确的状态,增删改都会改变平衡树各节点中的索引数据内容,数据库必须重新梳理树结构,这会带来不小的性能开销。

非聚集索引
非聚集索引和聚集索引一样,都采用平衡树作为数据结构,索引树中各节点的值来自表中的索引字段。
每次给字段建一个新索引,字段中的数据就会被复制一份出来,用于生成索引。因此,给表添加索引,会增加表的体积,占用磁盘存储空间。
非聚集索引和聚集索引的区别在于,通过聚集索引可以查到需要查找的数据,而通过非聚集索引可以查到记录对应的主键值,再使用主键的值通过聚集索引查找到需要的数据。

覆盖索引--联合索引(复合索引)
从非聚集索引中就可以得到查询的记录,而不需要查询聚集索引中的记录,这样会减少IO操作。
联合索引是指对表中多个字段进行索引。规定从左到右使用索引字段,一个查询只使用索引的一部分,使用原则是最左优先,例如联合索引包含(A、B、C)三个字段,只支持A、AB、ABC三种组合进行查找,不支持B、C、BC组合。

平衡树
即平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
平衡二叉树的常用算法有红黑树、AVL、Treap、伸展树、SBT等。

3、索引的类型(Mysql)

普通索引(normal):最基本的索引,它没有任何限制。
唯一索引(unique):索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
全文索引(full text):主要用来查找文本中的关键字,而不是直接与索引中的值相比较,只有char、varchar,text 列上可以创建全文索引。解决模糊查询效率低的问题。

4、矩阵(二维数组)填数字,每一行各列数据从小到大排列,每行数据的和从小到大排列

基本思路:先将数字放入一个临时集合,当集合中元素数量等于矩阵行数和列数的乘积时,先给集合排序,再将集合数据放入矩阵,并清除临时集合中的数据。具体实现代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class MatrixAddAndSort {
	
	public static void main(String[] args) {
		testMatrixAddAndSort();
	}
	
	public static void testMatrixAddAndSort(){
		int matrixSize = 5;
		int templen = matrixSize*matrixSize;
		
		int[][] matrix = new int[matrixSize][matrixSize];
		List<Integer> temp = new ArrayList<>(templen);
		Random random = new Random();
		for (int i = 0; i < 100; i++) {
			temp.add(random.nextInt(100));
			if((temp.size() % templen) == 0){
				//排序
				Collections.sort(temp);
				//放入二维数组
				for (int k = 0; k < matrix.length; k++) {//行
					int rowStart = matrixSize * k;
					for (int j = 0; j < matrix[k].length; j++) {//列
						matrix[k][j] = temp.get(rowStart+j);
					}
				}
				//打印二维数组
				for (int k = 0; k < matrix.length; k++) {//行
					for (int j = 0; j < matrix[k].length; j++) {//列
						System.out.print(matrix[k][j] + "  ");
					}
					System.out.println();
				}
				//清空临时list
				temp.clear();
				System.out.println("-------------------");
			}
		}
	}
}

5、读取数据库一张表中所有数据,多线程查询出,数据不能重复

基本思路:没整明白面试官真正要问的要点,好像意思是让我确定每个线程读取数据的起始行,这样的话就和分页的起始位置有点像了。具体实现代码如下:

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.jdbc.core.JdbcTemplate;
import com.alibaba.druid.pool.DruidDataSource;

public class MultThreadReadDataTable {
	
	private final static String driverClass = "com.mysql.jdbc.Driver";
	private final static String jdbcUrl = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8";
	private final static String username = "root";
	private final static String password = "root";
	
	public static JdbcTemplate getJdbcTemplate(){
		DruidDataSource ds = new DruidDataSource();
		ds.setDriverClassName(driverClass);
		ds.setUrl(jdbcUrl);
		ds.setUsername(username);
		ds.setPassword(password);
		JdbcTemplate jt = new JdbcTemplate(ds);
		return jt;
	}
	
	public static void main(String[] args) {
		JdbcTemplate jt = getJdbcTemplate();
		//获取表中总记录数
		List<Map<String, Object>> list = jt.queryForList("select count(id) as num from data_search");
		int maxNum = Integer.parseInt(list.get(0).get("num").toString());
		//线程池中线程数量
		int fixedNum = 10;
		//每个线程查询记录条数
		int pageSize = 10;
		//总页数
		int totalPage = 0;
		if(maxNum % pageSize == 0){
			totalPage = maxNum / pageSize;
		}else{
			totalPage = maxNum / pageSize + 1;
		}
		
		ExecutorService es = Executors.newFixedThreadPool(fixedNum);
		for (int i = 0; i < totalPage; i++) {
			final int count = i;
			es.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						Thread.sleep(50);
						List<Map<String, Object>> list = jt.queryForList("select * from data_search limit " + pageSize*count + "," + pageSize);
						for (Map<String, Object> map : list) {
							System.out.println(Thread.currentThread().getName() + ": " + map.get("name"));
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
		es.shutdown();
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值