校招面试题7------京东

7.Linux命令相关,问有一个文件A.txt,里面有许多行,找出其中带关键字'B'的行,并统计重复度。

cat  filename |grep  关键字

搜索命令grep

8.假如在服务器上执行一个进程时,你发现服务器很卡顿,你会怎么查找原因。

检查进程,有否内存泄漏

6.JDK1.8和之前版本的区别

JDK7新特性:

1,switch中可以使用字串了

2、在try catch异常扑捉中,一个catch可以写多个异常类型,用"|"隔开

JDK8:

3、接口的默认方法

Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法

3.写一个单例模式。我写的是静态内部类的单例,然后他问我这个地方为什么用private,这儿为啥用static,这就考察你的基本功啦

类的构造函数定义为private的,保证其他类不能实例化此类,static保证每个类访问到的都是同一个。

饿汉模式:

public class Singleton{  

    private static Singleton instance = new Singleton();  

    private Singleton(){}  

    public static Singleton newInstance(){  

        return instance;  

    }  

} 缺点,在类加载之后就被创建,即使没有用到

懒汉模式:

public class Singleton{  

    private static Singleton instance = null;  

    private Singleton(){}  

    public static synchronized Singleton newInstance(){  

        if(null == instance){  

            instance = new Singleton();  

        }  

        return instance;  

    }  

}在特定时间加载,延迟加载

10.jvm内存模型?

1) 从JVM内存模型开始说起,在纸上画出大概的组成部分,然后说出每个组成部分的特点

线程隔离的有:虚拟机栈,本地方法栈和程序计数器;

线程共享的有:方法区(被虚拟机加载的类的元数据信息:如常量、静态变量、即时编译器编译后的代码。也成为永久代)和堆区(存放所有对象实例和数组);

程序计数器(Program Counter Register):

每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令,对于非Native方法,这个区域记录的是正在执行的VM原语的地址,如果正在执行的是Natvie方法,这个区域则为空(undefined)。此内存区域是唯一一个在VM Spec中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈:

本地变量表存放了编译期可知的各种标量类型(boolean、byte、char、short、int、float、long、double)、对象引用(不是对象本身,仅仅是一个引用指针)、方法返回地址等。其中long和double会占用2个本地变量空间(32bit),其余占用1个。

本地方法栈:

本地方法栈是为虚拟机使用到的Native方法服务。

堆:

绝大部分的对象实例和数组都在这里分配。

8.聚簇索引 和 非聚簇索引的区别 。下面贴一下核心内容:

建立聚族索引: CREATE CLUSTER INDEX index_name ON table_name(column_name1,column_name2,...);

存储特点:

聚集索引:表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。 在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。

非聚集索引 : 表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。

15.有没有用过哪些集合?

Collection       接口的接口     对象的集合 

├ List           子接口         按进入先后有序保存   可重复 

│├ LinkedList    接口实现类     链表     插入删除   没有同步   线程不安全 

│├ ArrayList     接口实现类     数组     随机访问   没有同步   线程不安全 

│└ Vector        接口实现类     数组                  同步        线程安全 

│   └ Stack 

├ Queue       子接口      队列集合

└ Set            子接口       仅接收一次,并做内部排序 

├ HashSet 

│   └ LinkedHashSet  插入的次序

└ TreeSet 


Map                接口      键值对的集合 

├ Hashtable                 接口实现类                同步        线程安全  键值非空

├ HashMap                   接口实现类                没有同步    线程不安全 

│├ LinkedHashMap  插入次序

│└ WeakHashMap 

├ TreeMap  基于红黑树,可以返回子树 排序的

└ IdentifyHashMap 

Collections 是针对集合类的一个帮助类。提供了一系列静态方法实现对各种集合的搜索、排序、线程完全化等操作。相当于对 Array 进行类似操作的类—— Arrays 。 

24.hashCode()和equals()方法的重要性体现在什么地方?

equals一般是用来实现两个对象内容的比较,如果不重写就会和==一样。一般重写equals方法的时候都会相应的重写hashCode方法。(重写hashCode方法是个难点)

Java中的HashMap使用hashCode()和equals()方法来确定键值对的索引,当根据键获取值的时候也会用到这两个方法。如果没有正确 的实现这两个方法,两个不同的键可能会有相同的hash值,因此,可能会被集合认为是相等的。而且,这两个方法也用来发现重复元素。所以这两个方法的实现 对HashMap的精确性和正确性是至关重要的。

如何保证key的唯一性?即hashCode和equals的实现原理

相等的对象必须具有相同的散列码,但散列码相同则不一定是相等的对象,而且不相等的对象也不一定需要有不同的散列码。

20.Synchronized和lock区别

在并发量比较小的情况下,synchronized是个不错的选择,但是在并发量比较高的情况下,其性能下降很严重,此时ReentrantLock是个不错的方案。
区别:

(1)Synchronized是java关键字,是内置特性;而Lock是一个类;

(2)Lock可以让等待锁的线程响应中断,而synchronized却不行;

(3)Lock可以提高多个线程进行读操作的效率;

(4)Synchronized的锁是自动释放的,Lock需要手动释放;

(5)Lock可以知道线程有没有成功获得锁。

22.一般线程和守护线程的区别

Daemon的作用是为其他线程的运行提供服务,比如说GC线程。thread.setDaemon(true)必须在thread.start()之前设置。 在Daemon线程中产生的新线程也是Daemon的。 

当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程

25.简单介绍下线程池的参数?你了解哪些线程池?线程池使用了什么设计模式?线程池使用时一般要考虑哪些问题?

java.util.concurrent.ThreadPoolExecutor;

corePoolSize:核心池的大小

maximumPoolSize:线程池最大线程数

keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。

threadFactory:线程工厂,主要用来创建线程;

handler:表示当拒绝处理任务时的策略,有以下四种取值:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 

ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

线程池状态:

static 
final int 
RUNNING    = 0;

static 
final int 
SHUTDOWN   = 1;

static 
final int 
STOP     = 2;

static 
final int 
TERMINATED = 3;

execute()

submit()

shutdown()

shutdownNow()立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务.

线程池的种类:

Executors.newCachedThreadPool();  //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE

Executors.newSingleThreadExecutor();   //创建容量为1的缓冲池

Executors.newFixedThreadPool(int);    //创建固定容量大小的缓冲池

Executors.newScheduleThreadPool创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。

一般需要根据任务的类型来配置线程池大小:

如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1

如果是IO密集型任务,参考值可以设置为2*NCPU

单个任务处理的时间很短而请求的数目却是巨大的。join和close都可以用来关闭线程池。不同的是,join会把队列中的任务执行完,而close则立刻清空队列,并且中断所有的工作线程。

线程池大小,死锁,系统资源不足,并发错误,线程泄漏(比如都在等待用户输入),任务过载(太多等待任务)。

29.Tcp连接4次挥手的原因。Time_wait等待超时了会怎样?

time_wait 状态本来就是等待2个msl就直接进入closed状态

TIME_WAIT状态维持时间是两个MSL时间长度,也就是在1-4分钟。Windows操作系统就是4分钟。

MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间.

time_wait存在的原因:

1.可靠的终止TCP连接。

2.保证让迟来的TCP报文段有足够的时间被识别并丢弃。


为什么要三次握手:

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。

为什么需要四次挥手:

原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。

33.说一说对java io的理解

在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.

适配器模式,改变接口来重复使用

把一个类的接口变成客户端能接受的另一种接口。

使两个接口不一样的类能一起工作。

InputStreamReader适配器实现了Reader接口,持有InputStream引用。这样Reader字节最终调用InputStream

InputStreamReader:对象+接口

 

装饰器模式,接口不变,增强原来对象的功能

赋予类更多的功能,

FileInputStream,

BufferedInputStream是具体实现者,把InputStream读取内容保存在内存中,增强了功能。

39.linux查询java进程

ps -ef | grep java

kill -9 [PID] -9 表示强迫进程立即停止

ps -ef |grep java

下面对命令选项进行说明:
-e 显示所有进程。
-f 全格式。

ps e 列出程序时,显示每个程序所使用的环境变量。
ps f 用ASCII字符显示树状结构,表达程序间的相互关系

grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。
ps -ef | grep java:
检查java进程是否存在

41.String,是否可以继承,“+”怎样实现,与StringBuffer,StringBuilder区别

因为有final关键字,所以不能被继承。

“+”是通过StringBuffer或者是StringBuilder的append()和toString()方法来实现的。

String类对象为不可变对象,StringBuffer类对象为可修改对象,可以通过append()方法来修改值;都是线程安全的。

StringBuilder线程不安全,但是效率比StringBuffer高。

43.servlet流程

Web Client 向Servlet容器(Tomcat)发出Http请求

Servlet容器接收Web Client的请求

Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。

Servlet容器创建一个HttpResponse对象

Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。

HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。

HttpServlet调用HttpResponse对象的有关方法,生成响应数据。

Servlet容器把HttpServlet的响应结果传给Web Client。

44.异常:Java中的两种异常类型是什么?他们有什么区别?

Java异常分为Exception和Error两大类型,Exception又分为运行时异常(RuntimeException)和非运行时异常(如IOException),运行时异常代表运行时由Java虚拟机生成的异常,Java编译器要求Java程序必须捕获或生命所有的非运行时异常,但对运行时异常可以不做处理。

Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。这里有Java异常处理的一些小建议。

Java中Exception和Error有什么区别?

方法运行过程中如果发生了意外,方法将生成一个相应类型的异常,并把它交给运行时系统,这一过程称为抛出。运行时系统受到异常后,会寻找相应的代码来处理,这一过程称为捕获。

Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error是指Java虚拟机内部发生错误,由虚拟机生产并抛出,定义了不期望被用户程序捕获的异常。

Java的异常处理方式有两种:(1)try-catch-finally;(2)throws。

为什么使用自定义异常?

因为项目中有时会有符合Java语法,但是不符合业务逻辑的情况,这时就需要自定义异常了。

48.session/cookie,什么是cookie?session和cookie有什么区别?

cookie是Web服务器发送给浏览器的一块信息。浏览器会在本地文件中给每一个Web服务器存储cookie。以后浏览器在给特定的Web服务器发请求的时候,同时会发送所有为该服务器存储的cookie。下面列出了session和cookie的区别:

无论客户端浏览器做怎么样的设置,session都应该能正常工作。客户端可以选择禁用cookie,但是,session仍然是能够工作的,因为客户端无法禁用服务端的session。

在存储的数据量方面session和cookies也是不一样的。session能够存储任意的Java对象,cookie只能存储String类型的对象。

设置session有效期的方法有:

(1)在Tomcat的server.xml中定义;

(2)在工程的web.xml中定义;

(3)通过session.setMaxInactiveInterval(1000);

判断session是否失效:

request.getSession(false) == null ?

清楚session中的信息:session.invalidate();

Cookie可以设置有效期:cookie.setMaxAge(120);

在禁用Cookie的情况下使用Session:response.encodeurl(url);

51.DNS的解析流程

1、在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。 

2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。 

3、如果hosts与本地DNS解析 器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的 域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。 

4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。 

5、如果本地DNS服务器本地区域文 件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务 器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负 责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址
 (qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到 www.qq.com主机。 

6、如果用的是转发模式,此DNS服 务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地 DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

当应用过程需要将一个主机域名映射为IP地址时,就调用域名解析函数,解析函数将待转换的域
名放在DNS请求中,以UDP报文方式发给本地域名服务器。 本地的域名服务器查到域名后,将对应的IP地址放在应答报文中返回。同时域名服务器还必须具有连向其他服务器的信息以支持不能解析时的转发。若域名服务器
 不能回答该请求,则此域名服务器就暂成为DNS中的另一个客户,向根域名服务器发出请求解析,根域名服务器一定能找到下面的所有二级域名的域名服务器,这样以此类推,一直向下解析,直到查询到所请求的域名。

52.Object中的方法

54.进程和线程的区别是什么?

进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。

进程是CPU分配资源的最小单位,线程是CPU调度和程序执行的最小单位;

一个进程有几个(至少一个)线程组成,他们共享进程资源(方法区+堆区),同一个人进程可以有多个线程并发,一个线程可以创建和撤销另一个线程;

进程有自己的独立地址空间,线程只有自己的栈区和程序计数器;

进程切换需要很大的开销,线程开销相对较小。

协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。

1.数据库索引:
数据库索引;(高频)

CREATE CLUSTER INDEX id 

索引的实现通常使用B树及其变种B+树。

优点:加快查询速度;

缺点:占用空间,维护起来比较耗时;

建议使用索引的地方:主键,外键;需要排序或者根据范围来检索的列;经常需要搜索的列;WHERE子句中的列。

不创建索引的列:查询很少用到的列;只有很少数据值的列;修改性远远大于检索性的列。

索引类型有:主键索引,唯一索引,聚集索引。

将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。

而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往 往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。当程序要
 读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返 回,程序继续运行。
索引类型(全文索引),底层实现(B+树),什么情况下索引会失效

索引是对数据库表中一列或多列的值进行排序的一种结构。

唯一索引、主键索引和聚集索引。

MySQL目前主要有以下几种索引类型:HASH,BTREE。

HASH,hash很适合做索引,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行数据。

2.以下几种情况,将导致索引失效:

如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因);

对于多列索引,不是使用的第一部分,则不会使用索引
3.like查询是以%开头

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引

5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
3.数据库优化(索引、存储引擎、sql优化、视图)

1.适当建立索引:对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引,但索引并不是越多越好:

(1)应尽量避免在 where 子句中对字段进行 null 值判断,应尽量避免在 where 子句中使用 != 或 <> 操作符,以及like "%aa",使用参数, or (如果一个字段有索引,一个字段没有索引),in 和 not in 也要慎用,应尽量避免在where子句中对字段进行函数操作,不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

2.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

3.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

4.select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。

5.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。

6.选择适当的字段类型,特别是主键:尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型。
索引的实现通常使用B树及其变种B+树。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值