首页 > 互联网公司java面试题(一)

互联网公司java面试题(一)

1、JDK和JRE区别?

JDK是整个JAVA的核心,包括了Java运行环境JRE,一堆Java工具和Java基础的类库。

通过JDK开发人员将源码文件(java文件)编译成字节码文件(class文 件)。

JRE是Java运行环境,不含开发环境,即没有编译器和调试器。将class文件加载到内存准备运行。

 

2、final关键字,抽象类可以使用final修饰吗? 

1.用来修饰数据,包括成员变量和局部变量,该变量只能被赋值一次且它的 值无法被改变。对于成员变量来讲,必须在声明时或者构造方法中对它赋值;
2.修饰方法,表示该方法无法被重写;
3.修饰类,表示该类无法被继承。注:抽象类是被用于继承的,final修饰代表不可修改、不可继承的。所以不能用final修饰抽象类。

 

3、JAVA容器

(1)ArrayList底层数组实现,封装了常见的增删改查操作,并且支持动态扩容。适合查找多的场合。
(2)LinkedList基于链表实现的列表。适合增删情况较多的场合。
(3)TreeSet,基于二叉排序树(红黑树)实现的。TreeSet里最典型的就是它用到了两种排序方式,即基于元素对象自身的实现的Comparable接口的自然排序,以及基于更为灵活不与单个元素绑定的Comparator接口的客户化排序。自己在构造的时候传入一个比较器即可。
(4)HashMap是用来存储键值对的映射关系,底层是用数组+链表实现的。结合put操作讲一下。
(5)HashSet其实就是基于HashMap实现的,只不过将值固定为一个固定的值。
(6)LinkedHashMap,支持按照插入顺序排序。
(7)PriorityQueue优先级队列,一个基于优先级堆的无界优先级队列 

 

4、多线程安全在三个方面体现:

1.原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作; 
2.可见性:一个线程对主内存的修改可以及时地被其他线程看到;
3.有序性:程序执行的顺序按照代码的先后顺序执行,由于指令重排序,结果一般杂乱无序。

 

5、JAVA怎么保证线程安全?

(1)保证原子性常用的保证Java操作原子性的工具是锁和同步方法(或者同步代码块)。使用锁,可以保证同一时间只有一个线程能拿到锁,也就保证了同一时间只有一个线程能执行申请锁和释放锁之间的代码。与锁类似的是同步方法或者同步代码块。使用非静态同步方法时,锁住的是当前实例;使用静态同步方法时,锁住的是该类的Class对象;使用静态代码块时,锁住的是synchronized关键字后面括号内的对象。无论使用锁还是synchronized,本质都是一样,通过锁来实现资源的排性,从而实际目标代码段同一时间只会被一个线程执行,进而保证了目标代码段的原子性。这是一种以牺牲性能为代价的方法。(2)保证可见性 

   Java提供了volatile关键字来保证可见性。

   由于JMM是基于共享内存实现线程通信的,所以会存在缓存一致性的问题。

   当使用volatile修饰某个变量时,它会保证对该变量的修改会立即被更新到内存中,并且将其它缓存中对该变量的缓存设置成无效。

   因此其它线程需要读取该值时必须从主内存中读取,从而得到最新的值。(3)保证顺序性

   编译器和处理器对指令进行重新排序时,会保证重新排序后的执行结果和代码顺序执行的结果一致,所以重新排序过程并不会影响单线程程序的执行,却可能影响多线程程序并发执行的正确性。

   Java中可通过volatile在一定程序上保证顺序性,另外还可以通过synchronized和锁来保证顺序性。

   synchronized和锁保证顺序性的原理和保证原子性一样,都是通过保证同一时间只会有一个线程执行目标代码段来实现的。

   除了从应用层面保证目标代码段执行的顺序性外,JVM还通过被称为happens-before原则隐式地保证顺序性。

   两个操作的执行顺序只要可以通过happens-before推导出来,则JVM会保证其顺序性,反之JVM对其顺序性不作任何保证,可对其进行任意必要的重新排序以获取高效率。

 

6、有没有其他方法保证线程安全?

有。尽可能避免引起非线程安全的条件——共享变量。

如果能从设计上避免共享变量的使用,即可避免非线程安全的发生,也就无须通过锁或者synchronized以及volatile解决原子性、可见性和顺序性的问题。

还有不可变对象可以使用final修饰的对象保证线程安全,由于final修饰的引用型变量(除String外)不可变是指引用不可变,但其指向的对象是可变的,所以此类必须安全发布,即不能对外提供可以修改final对象的接口。

 

7、JAVA怎么避免死锁?

1、加锁顺序 
当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。
2、加锁时限 
在尝试获取锁的时候加一个超时时间,这也就意味着在 尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行。
3、死锁检测
死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。
除此之外,每当有线程请求锁,也需要记录在这个数据结构中。当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。
那么当检测出死锁时,这些线程该做些什么呢?一个可行的做法是释放所有锁,回退,并且等待一段随机的时间后重试。

这个和简单的加锁超时类似,不一样的是只有死锁已经发生了才回退,而不会是因为加锁的请求超时了。 虽然有回退和等待,但是如果有大量的线程竞争同一批锁,它们还是会重复地死锁。一个更好的方案是给这些线程设置优先级,让一个(或几个)线程回退,剩下的线程就像没发生死锁一样继续保持着它们需要的锁。如果赋予这些线程的优先级是固定不变的,同 一批线程总是会拥有更高的优先级。为避免这个问题,可以在死锁发生的时候设置随机的优先级。

 

8、数据库为什么建立索引?

优点:第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点:第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
适合应用索引的:经常需要搜索的列上,经常需要范围查询的,主键等。
不适合引用索引的:经常不用来查询的,大字段的比如text段等。

 

9、硬盘里一个50G大小的文件和另一个100G文件,里面存储着不同的名字,如何在一个内存很小的电脑上实现两个文件的交集运算。

方法一:先用哈希切分,再用分桶+组内Hash索引的方法
将一个大文件里的数据使用一个哈希函数进行切分为许多小的文件,这样相同的数据一定会进入同一个文件当中去,并进行文件编号。

对另外一个文件也是用相同的哈希函数进行切分为相同数目的小文件,这样我们只需要将相同编号里的文件进行比较。这样其时间复杂度就会降低为 O(n)。

相同的文件查找时可以先对一个文件建立hash索引(桶+链表),然后对另一个文件依次按照索引进行查找。若hash值相同在进行进一步比较即可。

方法二:位图方法 O(n) 这有个前提是文件中必须存储的是数字。那么根据位图,我们可以将第一个文件中所有数据映射到位图中去。

然后再不断导入第二个文件,如果发现某个数字已经存储在位图中,就说明这是两个文件的交集。

方法三:近似解-布隆过滤器 O(n) 将A文件每个数据经过多个Hash函数映射到一个位图上,然后第二个文件同 样的做法,如果全部命中,说明相同。否则说明不存在。但是这个有一定的错误率。

方法四:多路归并排序 Onlog(n)+O(n) 先将文件划分为很多等量的小文件。然后对每个小文件导入内存进行内部排 序。这样就有了很多有序的小文件。

然后对很多有序的小文件进行多路归并排序,然后不断写入大文件即可。(Onlog(n))最终就得到了一个有序的大文件。最后对两个有序的大文件进行查找相同的值即可(O(n))。

 

转载于:https://www.cnblogs.com/strong-FE/p/11482912.html

更多相关:

  • 多线程有什么好处?提高CPU的利用率,更好地利用系统资源,使用Monitor类可以同步静态/实例化的方法的全部代码或者部分代码段,使用不同的同步类创建自己的同步机制。多线程指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程提升整体处理性能。多线程是指程序中包含多个执行流,即...

  • Step1:在界面主函数的构造函数中初始化多线程 auto mythread = new QThread(); //新建connect(mythread , &QThread::finished, mythread, &QObject::deleteLater);//线程运行结束后释放内存object1->moveToThread...

  • 一、thread的基本用法 参见C++使用thread类多线程编程 。 二、类外使用多线程,访问类的成员 这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数。 #include #include #include using namesp...

  • 本博文是根据中科大信息学院谭立湘老师的课件加上自己的理解整理出来的 ************************************************************************************ NVIDIA在2007年推出CUDA这个统一计算架构 CUDA的基本思想是支持大量的线程级并...

  • 一、parallel communication patterns   并行通信模式 Map:映射,在特定的位置读取和写入。 Gather:收集,从多个不同的位置读入,写入一个位置。 Scatter:分发,写入多个位置。 Transpose转置 结构数组缩写为AOS,数组结构缩写为SOA 转置运算是指任务重新排序内存中的数...

  • 本文来自 运维人生 ,作者:fly是个稻草人链接:http://www.ywadmin.com/?id=76误删除linux系统文件了?不用急,本文将给你一个恢复linux文件的方法,让你轻松应对运维中的各风险问题。方法总比问题多~说在前面的话针对日常维护操作,难免会出现文件误删除的操作。大家熟知linux文件系统不同win有回收...

  • 原文来自SecIN社区—作者:WiHat0x00 什么是WebShell渗透测试工作的一个阶段性目标就是获取目标服务器的操作控制权限,于是WebShell便应运而生。Webshell中的WEB就是web服务,shell就是管理攻击者与操作系统之间的交互。Webshell被称为攻击者通过Web服务器端口对Web服务器有一定的操作权限,而...

  • 断电时文件系统发生了什么?硬盘又发生了什么?下一次开机时写到一半的文件在系统层面还在吗?在底层还在吗?更进一步的, 文件系统如何保证事务性, 会不会存在某种极端情况导致例如最后几个bit还没写完, 文件系统却认为它成功了的情况?回答不限任何文件系统,谢谢!下面是「北极」的回复分享断电的一瞬间,很多事情是无法确定的:1. 你无法确定...

  • 接到项目需求。需要搭建一个页面进行交互,慢慢来b (2).jpg使用python django框架进行页面的搭建在项目文件下打开窗口,输入命令;django-admin startproject helloword#在文件helloword/helloword/创建view.py在view.py文件中输入以代码from django....

  • 常见的错误集合解决方案(一)No.1提示错误'Microsoft.VC90.CRT,version="9.0.21022.8"把Microsoft.NET Framework 3.5.1下面的全部勾选上。No.2解决Qt Designer设计的图标但是VS生成不显示问题描述:在Qt designer中为菜单栏和工具栏设计的图标,但是...