万科java_万科面试总结

1.集合。ArrayList和linkedList的区别?hashMap实现,treeMap实现?如何自己实现一个treeMap?

treeMap的存储结构是二叉树。键不能重复,值可以重复,一个键对应一个值,无序,可以对key进行排序。

TreeMap实现了SotredMap接口,它是有序的集合。而且是一个红黑树结构,每个key-value都作为一个红黑树的节点。如果在调用TreeMap的构造函数时没有指定比较器,则根据key执行自然排序。这点会在接下来的代码中做说明,如果指定了比较器则按照比较器来进行排序。

http://2.io的掌握?如何复制一个文件?过程?平时用过哪些流?前边带buffer的流和一般的流有啥区别?读文件的时候用什么数据去接收?是否用过File.copy().这种方法?

Files.copy("","");

public static Path copy(Path source, Path target, CopyOption... options)

throws IOException

{

FileSystemProvider provider = provider(source);

if (provider(target) == provider) {

// same provider provider.copy(source, target, options);

} else {

// different providers CopyMoveHelper.copyToForeignTarget(source, target, options);

}

return target;

}

3.缓存和缓冲的区别?

字节流和字符流的区别:

1)字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。

2)字节流默认不使用缓冲区;字符流使用缓冲区。

3)字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。

4.是否了解nio?

NIO流与IO流的区别

面向流与面向块IO流是每次处理一个或多个字节,效率很慢(字符流处理的也是字节,只是对字节进行编码和解码处理)。

NIO流是以数据块为单位来处理,缓冲区就是用于读写的数据块。缓冲区的IO操作是由底层操作系统实现的,效率很快。

阻塞式与非阻塞式IO流是阻塞式的,使用read()与write()方法时,执行期间只能等待该方法完成。

NIO流是非阻塞式的,执行读写时依然可以做别的事情,不会阻塞线程,提高资源利用率,NIO流的Selector就是非阻塞式的。

NIO加入了Selector(选择器)Selector可以让一个线程监视多个Channel,只需要一个线程处理所有管道,减少线程开销。

nio流的相关类都放在java.nio包中,大体如下:java.nio 包:包含各种类型的Buffer(缓冲区)

java.nio.channels包:包含各种Channel(管道) 和Selector(选择器)

java.nio.charset包:包含各种处理字符集的类

Buffer(缓冲区)常用ByteBuffer 和 CharBuffer,还有一系列值类型Buffer,可以应用于不同类型。

所有Buffer都是抽象类,无法直接实例化。创建缓冲区要调用XxxBuffer allocate(),参数是缓冲区容量。

缓冲区数据存放在内存中,读写效率高。缓冲区有记录指针,能改变读写的起始点,根据不同需求,灵活处理数据。

Buffer参数说明capacity(容量):缓冲区支持的最大容量。

position(记录指针位置):是缓冲区读写数据的起始点,初始值为0。position随着数据的加入而改变,例如读取2个数据到Buffer中,则position = 2。

limit(界限):是缓冲区读写数据的终止点,limit之后的区域无法访问。

mark(标记):mark在0~position之间,设置该值就会把position移动到mark处。

Buffer的常用方法:flip():确定缓冲区数据的起始点和终止点,为输出数据做准备(即写入通道)。此时:limit = position,position = 0。

clear():缓冲区初始化,准备再次接收新数据到缓冲区。position = 0,limit = capacity。

hasRemaining():判断postion到limit之间是否还有元素。

rewind():postion设为0,则mark值无效。

limit(int newLt):设置界限值,并返回一个缓冲区,该缓冲区的界限和limit()设置的一样。

get()和put():获取元素和存放元素。使用clear()之后,无法直接使用get()获取元素,需要使用get(int index)根据索引值来获取相应元素

参考文章;NIO流-理解Buffer、Channel概念和NIO的读写操作 - 乘风起 - 博客园​www.cnblogs.com

5.多线程了解多少?java中有哪几种锁?synchronize和lock的区别?乐观锁和悲观锁的区别?

java中的锁有:

常见的锁有:

Synchronize和lock

Synchronized,它就是一个:非公平,悲观,独享,互斥,可重入的重量级锁

ReentrantLock,它是一个:默认非公平但可实现公平的,悲观,独享,互斥,可重入,重量级锁。

ReentrantReadWriteLocK,它是一个,默认非公平但可实现公平的,悲观,写独享,读共享,读写,可重入,重量级锁。

相对于synchronize,ReentrantLock有一些高级操作:

中断等待

ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候。

线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断

如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情

ReentrantLock获取锁定有三种方式:lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁

tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false

tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;

lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到获取锁定,或者当前线程被别的线程中断

可实现公平锁

对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。

synchronized的优势

synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中

应用场景

在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;

按照锁的性质进行分类:

公平锁/非公平锁

公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象。对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。对于Synchronized而言,也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度,所以并没有任何办法使其变成公平锁。

乐观锁/悲观锁

乐观锁与悲观锁不是指具体的什么类型的锁,而是指看待并发同步的角度。悲观锁认为对于同一个数据的并发操作,一定是会发生修改的,哪怕没有修改,也会认为修改。因此对于同一个数据的并发操作,悲观锁采取加锁的形式。悲观的认为,不加锁的并发操作一定会出问题。乐观锁则认为对于同一个数据的并发操作,是不会发生修改的。在更新数据的时候,会采用尝试更新,不断重新的方式更新数据。乐观的认为,不加锁的并发操作是没有事情的。从上面的描述我们可以看出,悲观锁适合写操作非常多的场景,乐观锁适合读操作非常多的场景,不加锁会带来大量的性能提升。悲观锁在Java中的使用,就是利用各种锁。乐观锁在Java中的使用,是无锁编程,常常采用的是CAS算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新。

独享锁/共享锁

独享锁是指该锁一次只能被一个线程所持有。共享锁是指该锁可被多个线程所持有。对于Java ReentrantLock而言,其是独享锁。但是对于Lock的另一个实现类ReentrantReadWriteLock,其读锁是共享锁,其写锁是独享锁。读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。独享锁与共享锁也是通过AQS来实现的,通过实现不同的方法,来实现独享或者共享。对于Synchronized而言,当然是独享锁。

互斥锁/读写锁

上面讲的独享锁/共享锁就是一种广义的说法,互斥锁/读写锁就是具体的实现。互斥锁在Java中的具体实现就是ReentrantLock,读写锁在Java中的具体实现就是ReentrantReadWriteLock

6.除了使用Spring对bean进行管理外,还用Spring做过啥?Spring是如何整合mybatis的?mapper.xml和接口是如何通过Spring进行管理的?

1.在Spring容器中配置mybatis的session工厂

2.配置模版方法

3.最后将dao层实现类的bean中注入模板bean,在dao层中通过sqlSessionTemplate调用模板方法进行查询即可

@Override

public List findAllYonghu() {

return sqlSessionTemplate.selectList("dao.YonghuGongNeng.findAllYonghu");

}

或者通过继承SqlSessionDaoSupport

借助于继承于父类中的 setSqlSessionFactory将sqlSessionFactory的bean注入实现类的bean,调用其方法实现

public class YonghuGongNengimpl extends SqlSessionDaoSupport implements YonghuGongNeng {

@Override

public List findAllYonghu() {

return getSqlSession().selectList("dao.YonghuGongNeng.findAllYonghu");

}

继承父类与模板方法相比,可以少配置一个sqlSessionTemplate的bean

7.lambda表达式?什么是函数式编程?lambda表达式来实现和匿名内部类实现的区别?

jdk8中的lambda表达式可以取代某些匿名内部类,但是并不是可以取代所有的匿名内部类的。只能取代是函数式接口的简写。

参考文档:

如何理解mapreduce思想?

8.python和java的编程的区别?思想上

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值