近期云医购面试

笔试部分

进去填了表先做了一套笔试题,下面总结一下遇到的题目(顺序记不清了):
一、sql优化方法(随便写几种);

1、对查询进行优化,应尽量避免全表扫描,首先应考虑在 whereorder by 涉及的列上建立索引。    
    
2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:    
select id from t where num is null    
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:    
select id from t where num=0    
    
3、应尽量避免在 where 子句中使用!=<>操作符,否则将导致引擎放弃使用索引而进行全表扫描。    
    
4、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:    
select id from t where num=10 or num=20    
可以这样查询:    
select id from t where num=10    
union all    
select id from t where num=20    
    
5innot in 也要慎用,否则会导致全表扫描,如:    
select id from t where num in(1,2,3)    
对于连续的数值,能用 between 就不要用 in 了:    
select id from t where num between 1 and 3    
    
6、下面的查询也将导致全表扫描:    
select id from t where name like '%abc%'    
    
7、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:    
select id from t where num/2=100    
应改为:    
select id from t where num=100*2    
    
8、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:    
select id from t where substring(name,1,3)='abc'--name以abc开头的id    
应改为:    
select id from t where name like 'abc%'    
    
9、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。    
    
10、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。    
    
11、不要写一些没有意义的查询,如需要生成一个空表结构:    
select col1,col2 into #t from t where 1=0    
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:    
create table #t(...)    
    
12、很多时候用 exists 代替 in 是一个好的选择:    
select num from a where num in(select num from b)    
用下面的语句替换:    
select num from a where exists(select 1 from b where num=a.num)    
    
13、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。    
    
14、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insertupdate 的效率,    
因为 insertupdate 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。    
一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。    
    
15、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。    
这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。    
    
16、尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,    
其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。    
    
17、任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。    
    
18、避免频繁创建和删除临时表,以减少系统表资源的消耗。
 
19、临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。    
    
20、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,    
以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert21、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。    
    
22、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。    
    
23、使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
 
24、与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。
在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
 
25、尽量避免大事务操作,提高系统并发能力。
 
26、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

二、GC算法
GC算法博客链接

三、new Integer(123)和 Integer.valueOf(123) 的区别?

new Integer(123)每次都会创建一个新的对象;
Integer.valueOf(123)会调用缓存池中的对象,多次调用会取得同一个对象的引用。

valueOf()方法首先会判断i是否在缓存池中,如果在的话就会直接返回缓存池中的内容,如果没有,就会用new Integer()创建一个新的对象。

下面是Integer的部分源码:

	private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            // 这一段可以不用仔细去了解,大概意思应该是可以通过配置文件来调整high的值。
            int h = 127; // 默认high的值为127
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127); // 判断设置的值与127默认值哪个大取哪个
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1]; // 创建缓存数组
            int j = low;// j = -128
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);// 在数组[0,high + (-low)]中对应填入-128,-127,......,0,1,.....high个值。

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

通过上面的源码分析,可以知道默认的Integer缓存池的大小范围是-128~127。也是是说在这个范围里面,只要缓存池中有需要的值,会直接从缓存池中来获取,而不是重新new一个对象。

四、Mysql的索引类型有哪些?
1.普通索引
2.唯一索引
3.主键索引
4.组合索引
5.全文索引

此为博客链接具体说明MySQL不同索引的区别
五、String、StringBuffer、StringBuild区别?

String 是 Java 语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是典型的 Immutable 类,被声明成为 final class,所有属性也都是 final 的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String 对象。由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。

StringBuffer 是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,我们可以用 append 或者 add 方法,把字符串添加到已有序列的末尾或者指定位置。StringBuffer 本质是一个线程安全的可修改字符序列,它保证了线程安全,也随之带来了额外的性能开销,所以除非有线程安全的需要,不然还是推荐使用它的后继者,也就是 StringBuilder。

StringBuilder 是 Java 1.5 中新增的,在能力上和 StringBuffer 没有本质区别,但是它去掉了线程安全的部分,有效减小了开销,是绝大部分情况下进行字符串拼接的首选。

字符串拼接效率:StringBulider>SringBuffer>String

六、finalize,finally,final的区别?

fnal可以用来修饰类、方法、变量,分别有不同的意义,fnal修饰的 class代表不可以继承扩展,fnal的变量是不可以修改的,而fnal的方法也是不可以重(override)

finally则是java保证重点代码一定要被执行的一种机制。使用try-finally或者try-catch-finally来进行类似关闭JDBC链接。保证unlock锁等动作。

finalize是基础类java.lang.Object的一个方法,他的设计目的是保证对象在被垃圾收集前完成特定资源的回收。finalize机制不推荐使用,jdk9开始被标记为deprecated。

使用final修饰参数或者变量,也可以清楚地避免意外赋值导致的编程错误。final变量产生了某种程度的不可变的效果,所以,可以用于保护只读数据,有利于减少额外的同步开销。

七、spring有几种注入方式?
Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的注入。

八、Post和Get的区别?

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。

具体参透Post和Get的区别博客链接

九、HashMap和HashTable的区别?
继承的父类不同: Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
线程安全不同:HashMap是线程不安全的HashTable是线程安全的。
详谈HashMap和HashTable的区别博客链接

十、 ConcurrentHashMap

ConcurrentHashMap总结

十一、浅拷贝和深拷贝区别?

如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
深入理解浅拷贝与深拷贝

十二、JDBC链接过程;
1、加载JDBC驱动程序。

在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现。成功加载后,会将Driver类的实例注册到DriverManager类中。

2、提供JDBC连接的URL。

连接URL定义了连接数据库时的协议、子协议、数据源标识。
书写形式:协议:子协议:数据源标识。

3、创建数据库的连接。

要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象, 该对象就代表一个数据库的连接。
使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。

4、创建一个Statement,要执行SQL语句,必须获得java.sql.Statement实例。

Statement实例分为以下3 种类型:

(1)执行静态SQL语句。通常通过Statement实例实现。
(2)执行动态SQL语句。通常通过PreparedStatement实例实现。
(3)执行数据库存储过程。通常通过CallableStatement实例实现。

5、执行SQL语句。

Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute。

十三、java中已有排序工具或者接口有哪些?

Arrays.sort()方法可对任何实现compareble接口的对象数组排序, 像Integer,String,这两种引用类型都实现了compareble接口,所以这两种类型的数组都可直接使用Arrays.sort()进行排序
之前写过的Collections与Comparator理解笔记

技术面部分

一个技术主管一起面四个人;
1.先让每个人讲讲大学参加过的比赛以及将来职业规划

2.每个人讲一下自己擅长的部分;
我讲了数据结构和算法部分,然后让现场口述一下快速排序的实现,讲完快排实现接着问了HashMap源码部分,讲了下hashcode;

3.现场说如果实现一个图书馆管理系统应该如何做?
需求分析、功能分析、管理分析、数据库分析一步步自由发言讨论。最后让每个人说一下实现步骤,由于正在学的一个ssm项目好没有完成,只是简单说了下工程建立、打包类型…

登录界面博客链接–图书馆管理系统(1)
JDBC连接数据库增删改查博客链接–图书馆管理系统(1)
图书馆管理系统(2)博客链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值