最近面试题总结10.12

1.java基本数据类型:

先说明两个词汇的基本概念:
bit (位):位是计算机中存储数据的最小单位,指二进制数中的一个位数,其值为“0”或“1”。

byte (字节):字节是计算机存储容量的基本单位,一个字节由8位二进制数组成。在计算机内部,一个字节可以表示一个数据或者一个英文字母,但是一个汉字需要两个字节表示。
1B=8bit 
1Byte=8bit
1KB=1024Byte(字节)=8*1024bit
1MB=1024KB
1GB=1024MB
1TB=1024GB

第二类、浮点数类型
float:单精度类型,32 位,后缀 F 或 f,1 位符号位,8 位指数,23 位有效尾数。

double:64 位,最常用,后缀 D 或 d,1 位符号位,11 位指数,52 位有效尾数。

java浮点型默认为double型,所以要声明一个变量为float型时,需要在数字后面加F或者f:

例如:double d = 88888.8;      float f = 88888.8f;  //不加f的话会报错

第三类、字符类型

char:16位,java字符使用Unicode编码,

第四类、布尔类型

boolean:true 真  和 false 假

 简单数据类型之间的转换
   在Java中整型、实型、字符型被视为简单数据类型,这些类型由低级到高级分别为

(byte,short,char)--int--long--float--double

更多可看:https://www.cnblogs.com/mxcl/p/7809959.html

2.工厂模式有什么好处?

 工厂模式的作用,为什么要用工厂模式?

  工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类。

  工厂模式可以降低代码重复。如果创建B过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。可以把这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的维护。

工厂模式可以减少错误,因为工厂管理了对象的创建逻辑,使用者不需要知道具体的创建过程,只管使用即可,减少了使用者因为创建逻辑导致的错误。

工厂模式的一些适用场景:

   对象的创建过程/实例化准备工作很复杂,需要很多初始化参数,查询数据库等

  类本身有好多子类,这些类的创建过程在业务中容易发生改变,或者对类的调用容易发生改变

  可以参考,计算器例子。

3.二维数组的初始化

int [][] a=new int[][]{{1,2,3},{2,3}};

int [][] a=new int[4][4];

int [][]a=new int[3][];

4.一维数组初始化

 int[] arr = new int[3];

int[] arr = null; 

int[] arr = {1, 2, 3};

int[] arr = new int[]{1, 2, 3};

5.多态:

 多态是同一个行为具有多个不同表现形式或形态的能力。

  它包括两种类型:
    静态多态性:包括变量的隐藏、方法的重载(指同一个类中,方法名相同[方便记忆],但是方法的参数类型、个数、次序不同,本质上是多个不同的方法);
    动态多态性:是指子类在继承父类(或实现接口)时重写了父类(或接口)的方法,程序中用父类(或接口)引用去指向子类的具体实例,从代码形式上看是父类(或接口)引用去调用父类(接口)的方法,但是在实际运行时,JVM能够根据父类(或接口)引用所指的具体子类,去调用对应子类的方法,从而表现为不同子类对象有多种不同的形态。

多态的优点

  • 1. 消除类型之间的耦合关系
  • 2. 可替换性
  • 3. 可扩充性
  • 4. 接口性
  • 5. 灵活性
  • 6. 简化性

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

6.封装:

  封装的好处:

  1. 封装可以隐藏实现的细节
  2. 让使用者只能通过实现写好的访问方法来访问这些字段,这样一来我们只需要在这些方法中增加逻辑控制,限制对数据的不合理访问、
  3. 方便数据检查,有利于于保护对象信息的完整性
  4. 便于修改,提高代码的可维护性

实现封装的方式:使用访问控制符

  java提供了三种访问权限,准确的说还有一种是默认的访问权限,加上它一共四种。

  • private   在当前类中可访问
  • default        在当前包内和访问
  • protected    在当前类和它派生的类中可访问
  • public          公众的访问权限,谁都能访问

7.把一个整数反转过来,这道你查一下,要注意正负数的情况

public class demo_exp_2 {

    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
    public static void main(String[] args){

        demo_exp_2 a = new demo_exp_2();
        System.out.println(a.reverse(-13232));
    }

}
View Code

简单代码如下:

public class Solution {  
    public int reverse(int x) {  
        int result = 0;  
        while (x != 0) {  
            result = result * 10 + x % 10; // 每一次都在原来结果的基础上变大10倍,再加上余数  
            x = x / 10; // 对x不停除10  
        }  
        return result;  
    }  
View Code

8.一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高?

public static void main(String[] args) {
        int total = 0;
        int height = 100;
        for (int i = 0; i < 10; i++) {
            System.out.print("第" + (i + 1) + "次落下时候高度:" + height + " ");
            total = total + height;
            height = height / 2;
            System.out.println("第" + (i + 1) + "次落下经过距离:" + total);
        }
    }
View Code

8.Mysql的数据类型

 主要包括以下五大类:

  整数类型:BIT、BOOL、TINY INT、SMALL INT、MEDIUM INT、 INT、 BIG INT

  浮点数类型:FLOAT、DOUBLE、DECIMAL

  字符串类型:CHAR、VARCHAR、TINY TEXT、TEXT、MEDIUM TEXT、LONGTEXT、TINY BLOB、BLOB、MEDIUM BLOB、LONG BLOB

  日期类型:Date、DateTime、TimeStamp、Time、Year

  其他数据类型:BINARY、VARBINARY、ENUM、SET、Geometry、Point、MultiPoint、LineString、MultiLineString、Polygon、GeometryCollection等

9.Mysql索引

  MySQL目前主要有以下几种索引类型:
  1.普通索引:是最基本的索引,它没有任何限制。
  2.唯一索引:与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
  3.主键索引:是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引
  4.组合索引:指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合
  5.全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。
  6.覆盖索引
 
 
 
 
 
数据库有哪些索引?
B tree、B+tree、哈希、全文、R-tree
 
 

为什么不实用二叉查找树或者红黑树作为数据库索引。

二叉树在处理海量数据时,树的高度太高,虽然索引效率很高,达到logN,但会进行大量磁盘io,得不偿失。而且删除或者插入数据可能导致数据结构改变变成链表,需要增进平衡算法。而红黑树,插入删除元素的时候会进行频繁的变色和旋转(左旋,右旋),很浪费时间。但是当数据量很小的时候,完全可以放入红黑树中,此时红黑树的时间复杂性比b树低。因此,综上考虑,数据库最后选择了b树作为索引。


B tree和B+ tree应用场景:

1.B树常用于文件系统,和少部分数据库索引,比如mongoDB。

2.B+树主要用于mysql数据库索引。


B+ tree对比B tree的优点

B树的每个节点除了存储指向 子节点的索引外,还要存储data域,因此单一节点指向子节点的索引并不是很多,树的高度较高,磁盘io次数较多。B+树的高度更低,且所有data都存储在叶子节点,叶子节点都处于同一层,因此查询性能稳定,便于范围查找。

 
 
10.联合索引的最左匹配原则
 
11.表连接
 
表连接有几种?
sql表连接分成外连接内连接交叉连接。
 
外连接:
  外连接包括三种,分别是左外连接、右外连接、全外连接。
  对应的sql关键字:LEFT/RIGHT/FULL OUTER JOIN,通常我们都省略OUTER关键字,写成LEFT/RIGHT/FULL JOIN。
  在左、右外连接中都会以一种表为基表,基表的所有行、列都会显示,外表如果和条件不匹配则所有的外表列值都为NULL。
  全外连接则所有表的行、列都会显示,条件不匹配的值皆为NULL。
 
内连接:内连接是用比较运算符比较要连接的列的值的连接,不匹配的行不会被显示。sql关键字JOIN 或者INNER JOIN,通常我们写成JOIN
 
交叉连接::没有where条件的交叉连接将产生连接表所涉及的笛卡尔积。即TableA的行数*TableB的行数的结果集。(TableA 3行*TableB 3行=9行)

12.关系型数据库三大范式

  要想满足第二范式必须先满足第一范式,想满足第三范式必须先满足第二范式。

第一范式:是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。(列数据的不可分割)

第二范式:要求数据库表中的每个行必须可以被唯一地区分,为实现区别通常需要为表加上一个列,以存储各个实例的唯一标识(主键)

第三范式:需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

简单总结就是:第一范式的关键词是列的原子性

       第二范式的关键词是不能包含部分依赖

       第三范式的关键词是不能包含传递依赖

更多:https://www.cnblogs.com/wsg25/p/9615100.html

13.list<T>、 list<?>、list<Object>的区别?

  List<T>、List<?>、List<Object>这三者都可以容纳所有的对象,

  但使用的顺序应该是首选List<T>,次之List<?>,最后选择List<Object>

原因如下:

(1) List<T>是确定的某一个类型
  List<T>表示的是List集合中的元素都为T类型,具体类型在运行期决定;List<?>表示任意类型,与List<T>类似,而List<Object>则表示List集合中的所有元素为Object类型,因为Object是所有类的父类,所以List<Object>也可以容纳所有的类类型,从这一字面意义上分析,List<T>更符合习惯:编码者知道它是某一个类型,只是在运行期才确定而已。

(2) List<T>可以进行读写操作
  List<T>可以进行诸如add、remove等操作,因为它的类型是固定的T类型,在编码期 不需要进行任何的转型操作。
  List<?>是只读类型的,不能进行增加、修改操作,因为编译器不知道List中容纳的是 什么类型的元素,也就无毕校验类型是否安全了,而且List<?>读取出的元素都是Object类 型的,需要主动转型,所以它经常用于泛型方法的返回值。注意,List<?>虽然无法增加、修 改元素,但是却可以删除元素,比如执行remove、clear等方法,那是因为它的删除动作与泛型类型无关。
  List<Object>也可以读写操作,但是它执行写入操作时需要向上转型(Upcast),在读 取数据后需要向下转型(Downcast),而此时已经失去了泛型存在的意义了。

14.数据库优化

1、选取最适用的字段属性

2、使用连接(JOIN)来代替子查询(Sub-Queries)

3、使用联合(UNION)来代替手动创建的临时表

4、事务

5、锁定表

6、使用外键

7、使用索引

8、优化的查询语句

MySQL性能优化的一些经验
	a.为查询优化你的查询
	b.学会使用EXPLAIN
	c.当只要一行数据时使用LIMIT 1
		当你查询表的有些时候只需要一条数据,请使用 limit 1。
	d.正确的使用索引
		索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索、拍下、条件,那么,请为其建立索引吧。
	e.不要ORDER BY RAND()
		效率很低的一种随机查询。
	f.避免SELECT *
		从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。必须应该养成一个需要什么就取什么的好的习惯。
	g.使用 ENUM 而不是 VARCHAR
		ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。
		如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。
	h.使用 NOT NULL
	k.垂直分割
		“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。
	l.拆分大的 DELETE 或 INSERT 语句
	
	m.越小的列会越快
		对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。
	n.选择正确的存储引擎
		在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。
		MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。
		InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。

 9.两个list查找相同元素!除了遍历外你还想到什么方法?

  从两个list中找到重复元素,很容易就想到两个for循环嵌套来实现,但是如果两个list都非常大的话,时间复杂度将非常大。所以这里介绍一种以空间换时间的方法。
1.因为list中是可以存在相同元素的,但是想以2来得到重复的元素,所以需要进行去重
2.将list中的元素放入map中,并对元素个数进行一个统计
3.将hashmap中value为2的key存入list

代码如下:

public class TestList {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<String>();

        list1.add("a");
        list1.add("b");
        list1.add("b");
        list1.add("c");

        list2.add("b");
        list2.add("c");
        list2.add("d");

        String duplicate = findDuplicate(list1, list2);
        System.out.println("duplicate element: " + duplicate);
    }

    private static String findDuplicate(List<String> list1, List<String> list2) {
        List<String> duplicate = new ArrayList<String>();
        Map<String, Integer> map = new HashMap<String, Integer>();
        //1.去重
        List<String> list3 = new ArrayList<String>(new HashSet<String>(list1));
        List<String> list4 = new ArrayList<String>(new HashSet<String>(list2));
        //2.将list中的元素加入map中并进行统计
        for (String s1 : list3) {
            map.put(s1, 1);
        }
        //3.将list中的元素加入map中并进行统计
        for (String s2 : list4) {
            map.put(s2, (map.get(s2) == null ? 1 : 2));
        }
        //4.将重复的元素放入list中
        for (Map.Entry<String, Integer> m : map.entrySet()) {
            if (m.getValue() == 2) {
                duplicate.add(m.getKey());
            }
        }
        return duplicate.toString();
    }
}
View Code

15.复习一下mybatis

16.数据库如果有某个字段忽然增大到几万的长度怎么办

  可以另外建一个表来存储这段数据,再有就是把字段切割成几段,原先的表里存对应的id ,避免原先的表数据量过大

原文地址:https://www.cnblogs.com/fzzzjjj/p/11663565.html