前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【BATJ面试必会】JAVA面试到底需要掌握什么?【下】

【BATJ面试必会】JAVA面试到底需要掌握什么?【下】

作者头像
乔戈里
发布2019-01-07 17:21:57
7530
发布2019-01-07 17:21:57
举报
文章被收录于专栏:Java那些事Java那些事

非对称加密,对称加密 对称加密(Symmetric Cryptography),又称私钥加密

  • 对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key),这种方法在密码学中叫做对称加密算法。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。对称加密通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率,是一个trade-off。

非对称加密(Asymmetric Cryptography),又称公钥加密

  • 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥(public key)和私钥(private key)。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。比如,你向银行请求公钥,银行将公钥发给你,你使用公钥对消息加密,那么只有私钥的持有人--银行才能对你的消息解密。与对称加密不同的是,银行不需要将私钥通过网络发送出去,因此安全性大大提高。

目前通信安全的方法

  • 将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。

Http, Https 区别 (*)

  • Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。

二者之间存在如下不同:

  • 端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443;
  • 资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源;
  • 开销:Https通信需要证书,而证书一般需要向认证机构购买;
  • Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。SSL协议是通过非对称密钥机制保证双方身份认证,并完成建立连接,在实际数据通信时通过对称密钥机制保障数据安全性.

长连接,短连接

  • http://www.cnblogs.com/0201zcr/p/4694945.html
  • connection:keep-alive

短连接

  • 模拟一下TCP短连接的情况: client 向 server 发起连接请求 server 接到请求,双方建立连接 client 向 server 发送消息 server 回应 client 一次读写完成,此时双方任何一个都可以发起 close 操作 在第 5 点钟,一般都是 client 先发起 close 操作。因为一般的 server 不会回复完 client 后就立即关闭连接。 当然也不排除有特殊的情况。 从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作
  • 管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段

长连接

  • 再模拟一下长连接的情况: client 向 server 发起连接 server 接到请求,双方建立连接 client 向 server 发送消息 server 回应 client 一次读写完成,连接不关闭 后续读写操作… 需要TCP保活功能。

应用场景

  • 长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。 每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接, 再操作的话那么处理速度会降低很多,所以每个操作完后都不断开, 再次处理时直接发送数据包就OK了,不用建立TCP连接。 例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误, 而且频繁的socket 创建也是对资源的浪费。
  • 而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源, 如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话, 那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

三次握手,四次挥手(*) 常问问题, 熟背

为什么是三次握手不是两次握手

  • 在只有两次“握手”的情形下,假设Client想跟Server建立连接,但是却因为中途连接请求的数据报丢失了,故Client端不得不重新发送一遍;这个时候Server端仅收到一个连接请求,因此可以正常的建立连接。但是,有时候Client端重新发送请求不是因为数据报丢失了,而是有可能数据传输过程因为网络并发量很大在某结点被阻塞了,这种情形下Server端将先后收到2次请求,并持续等待两个Client请求向他发送数据…问题就在这里,Cient端实际上只有一次请求,而Server端却有2个响应,极端的情况可能由于Client端多次重新发送请求数据而导致Server端最后建立了N多个响应在等待,因而造成极大的资源浪费

为什么是四次挥手

  • 双向通信
  • 假如现在你是客户端你想断开跟Server的所有连接该怎么做?第一步,你自己先停止向Server端发送数据,并等待Server的回复。但事情还没有完,虽然你自身不往Server发送数据了,但是因为你们之前已经建立好平等的连接了,所以此时他也有主动权向你发送数据;故Server端还得终止主动向你发送数据,并等待你的确认

GET POST区别

  • 在客户端, Get 方式在通过 URL 提交数据,数据 在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。
  • GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
  • 安全性问题。使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get ;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post 为好。
  • 安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说, GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。 POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了(比方说文章下面出现一条注解)。

TCP UDP区别 (*)

  • TCP是面向连接的,UDP是无连接的;
  • TCP是可靠的,UDP是不可靠的;
  • TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式;
  • TCP是面向字节流的,UDP是面向报文的;
  • TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信;
  • TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大;

从输入网址到获得页面的过程

  • (1). 浏览器查询DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
  • (2). 浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;
  • (3). TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;
  • (4). 服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;
  • (5). 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;
  • (6). 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

OSI网络体系结构与TCP/IP协议模型 (*)

enter image description here

enter image description here 物理层

  • 实现了相邻计算机节点之间比特流的透明传送,并尽可能地屏蔽掉具体传输介质和物理设备的差异,使其上层(数据链路层)不必关心网络的具体传输介质

数据链路层

  • 接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。

enter image description here 网络层

  • 将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路径.

传输层

enter image description here

  • 在源端与目的端之间提供可靠的透明数据传输,使上层服务用户不必关系通信子网的实现细节。在协议栈中,传输层位于网络层之上,传输层协议为不同主机上运行的进程提供逻辑通信,而网络层协议为不同主机提供逻辑通信,如下图所示.

会话层

  • 会话层是OSI模型的第五层,是用户应用程序和网络之间的接口,负责在网络中的两节点之间建立、维持和终止通信.

表示层

  • 数据的编码,压缩和解压缩,数据的加密和解密.

应用层

  • 用户的应用进程提供网络通信服务.

TCP和UDP分别对应的常见应用层协议 TCP

  • FTP,
  • Telnet,
  • SMTP,
  • POP3,
  • HTTP

UDP

  • DNS
  • SNMP(简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势)
  • TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务。

网络层的ARP协议工作原理

  • 网络层的ARP协议完成了IP地址与物理地址的映射。首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。

HTTP常见状态码

  • 1×× : 请求处理中,请求已被接受,正在处理
  • 2×× : 请求成功,请求被成功处理
  • 200 OK
  • 3×× : 重定向,要完成请求必须进行进一步处理
  • 301 : 永久性转移
  • 302 :暂时性转移
  • 304 : 已缓存
  • 4×× : 客户端错误,请求不合法
  • 400:Bad Request,请求有语法问题
  • 403:拒绝请求
  • 404:客户端所访问的页面不存在
  • 5×× : 服务器端错误,服务器不能处理合法请求
  • 500 :服务器内部错误
  • 503 : 服务不可用,稍等

HTTP协议是无状态的 和 Connection: keep-alive的区别

  • HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
  • 从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
  • Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间

属于网络112.10.200.0/21的地址是? (*) 笔试常考

  • 前21位为网络地址,后12位为主机地址。112 对应前8位,10对应第二个8位,因此200对应第3个8位又200的二进制表示为1100 1000 前面已经有了16位,因此11001 是属于网络地址的。000是属于主机地址 那么,最大的地址为【112(十进制)】【10(十进制)】【11001 111】【 11111111】转换为十进制为112.10.207.255 故网络的地址范围为: 112.10.200.0~112.10.207.255

某一速率为100M的交换机有20个端口,其一个端口上连着一台笔记本电脑,此电脑从迅雷上下载一部1G的电影需要的时间可能是多久?

  • 1GB/(100Mb/s ÷8,字节→比特)=81.92 s, 比81s大
  • 交换机在同一时刻可进行多个端口对之间的数据传输。每一端口都可视为独立的网段,连接在其上的网络设备独自享有全部的带宽,无须同其他设备竞争使用。

与10.110.12.29 mask 255.255.255.224属于同一网段的主机IP地址是?(*) 笔试常考

  • 通俗理解: 子网掩码为255.255.255.224=255.255.255.11100000,也就是讲第四个字节,有三位用来表示子网号(共有000,001,010….111等8个子网号) 请看题目给的是:10.110.12.29=10.110.12.29=10.110.12.00011101,从这里看,题目给出的IP所处子网号在000段,所以跟这个IP在一个网段的IP的前27位是定的:10.110.12.000 最后5位可以是00001~11110(全0和全1是不行的),也就是讲IP范围为 10.110.12.000 00000~ 10.110.12.000 11110

数据在计算机网络中的称法?

  • 应用层:报文
  • 运输层:报文段/用户数据报
  • 网际层:IP数据报/分组/包
  • 数据链路层:帧
  • 物理层:比特流

try catch finally (*) 笔试常见套路题

  • https://blog.csdn.net/aaoxue/article/details/8535754

OOM, Out of Memory 错误

常见OOM情况

  • Java堆内存溢出,此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。
  • Java永久代溢出,即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize=64m -XX:MaxPermSize=256m的形式修改。另外,过多的常量尤其是字符串也会导致方法区溢出。
  • java.lang.StackOverflowError, 不会抛OOM error,但也是比较常见的Java内存溢出。JAVA虚拟机栈溢出,一般是由于程序中存在死循环或者深度递归调用造成的,栈大小设置太小也会出现此种溢出。可以通过虚拟机参数-Xss来设置栈的大小。
  • 静态集合类

常用Linux命令

cd

  • cd /root/Docements # 切换到目录/root/Docements
  • cd ./path # 切换到当前目录下的path目录中,“.”表示当前目录
  • cd ../path # 切换到上层目录中的path目录中,“..”表示上一层目录

ls

  • -l :列出长数据串,包含文件的属性与权限数据等
  • -a :列出全部的文件,连同隐藏文件(开头为.的文件)一起列出来(常用)
  • -d :仅列出目录本身,而不是列出目录的文件数据
  • -h :将文件容量以较易读的方式(GB,kB等)列出来
  • -R :连同子目录的内容一起列出(递归列出),等于该目录下的所有文件都会显示出来

grep 命令常用于分析一行的信息,若当中有我们所需要的信息,就将该行显示出来,该命令通常与管道命令一起使用,用于对一些命令的输出进行筛选加工等等

  • grep [-acinv] [--color=auto] '查找字符串' filename
  • -a :将binary文件以text文件的方式查找数据
  • -c :计算找到‘查找字符串’的次数
  • -i :忽略大小写的区别,即把大小写视为相同
  • -v :反向选择,即显示出没有‘查找字符串’内容的那一行

find 寻找 find [PATH] [option] [action] 与时间有关的参数:

  • -mtime n : n为数字,意思为在n天之前的“一天内”被更改过的文件;
  • -mtime +n : 列出在n天之前(不含n天本身)被更改过的文件名;
  • -mtime -n : 列出在n天之内(含n天本身)被更改过的文件名;
  • -newer file : 列出比file还要新的文件名

cp 复制

  • -a :将文件的特性一起复制
  • -p :连同文件的属性一起复制,而非使用默认方式,与-a相似,常用于备份
  • -i :若目标文件已经存在时,在覆盖时会先询问操作的进行
  • -r :递归持续复制,用于目录的复制行为
  • -u :目标文件与源文件有差异时才会复制

mv 移动

  • -f :force强制的意思,如果目标文件已经存在,不会询问而直接覆盖
  • -i :若目标文件已经存在,就会询问是否覆盖
  • -u :若目标文件已经存在,且比目标文件新,才会更新

rm 删除

  • -f :就是force的意思,忽略不存在的文件,不会出现警告消息
  • -i :互动模式,在删除前会询问用户是否操作
  • -r :递归删除,最常用于目录删除,它是一个非常危险的参数

ps 查看进程

  • -A :所有的进程均显示出来
  • -a :不与terminal有关的所有进程
  • -u :有效用户的相关进程
  • -x :一般与a参数一起使用,可列出较完整的信息
  • -l :较长,较详细地将PID的信息列出
  • ps aux # 查看系统所有的进程数据
  • ps ax # 查看不与terminal有关的所有进程
  • ps -lA # 查看系统所有的进程数据
  • ps axjf # 查看连同一部分进程树状态

kill 该命令用于向某个工作(%jobnumber)或者是某个PID(数字)传送一个信号,它通常与ps和jobs命令一起使用,它的基本语法如下:kill -signal PID

  • 1:SIGHUP,启动被终止的进程
  • 2:SIGINT,相当于输入ctrl+c,中断一个程序的进行
  • 9:SIGKILL,强制中断一个进程的进行
  • 15:SIGTERM,以正常的结束进程方式来终止进程
  • 17:SIGSTOP,相当于输入ctrl+z,暂停一个进程的进行

killall

  • -i :交互式的意思,若需要删除时,会询问用户
  • -e :表示后面接的command name要一致,但command name不能超过15个字符
  • -I :命令名称忽略大小写 例如:
  • killall -SIGHUP syslogd # 重新启动syslogd

file 用于判断接在file命令后的文件的基本数据,因为在Linux下文件的类型并不是以后缀为分的

  • file filename

例如: file ./test

tar

  • -c :新建打包文件
  • -t :查看打包文件的内容含有哪些文件名
  • -x :解打包或解压缩的功能,可以搭配-C(大写)指定解压的目录,注意-c,-t,-x不能同时出现在同一条命令中
  • -j :通过bzip2的支持进行压缩/解压缩
  • -z :通过gzip的支持进行压缩/解压缩
  • -v :在压缩/解压缩过程中,将正在处理的文件名显示出来
  • -f filename :filename为要处理的文件
  • -C dir :指定压缩/解压缩的目录dir 常用tar命令
  • 压缩:tar -jcv -f filename.tar.bz2 要被处理的文件或目录名称
  • 查询:tar -jtv -f filename.tar.bz2
  • 解压:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录

cat 用于查看文本文件的内容,后接要查看的文件名,通常可用管道与more和less一起使用,从而可以一页页地查看数据

  • cat text | less # 查看text文件中的内容 注:这条命令也可以使用less text来代替

chgrp 改变文件所属所属用户组

  • chgrp [-R] dirname/filename
  • -R :进行递归的持续对所有文件和子目录更改

例如:

  • chgrp users -R ./dir # 递归地把dir目录下中的所有文件和子目录下所有文件的用户组修改为users

chown 改变文件所有者

chmod 改变文件权限

  • chmod [-R] xyz 文件或目录
  • -R:进行递归的持续更改,即连同子目录下的所有文件都会更改

vim

JVM类加载机制 (*)

面试有概率会问

enter image description here 加载

  • 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个Class文件获取,这里既可以从ZIP包中读取(比如从jar包和war包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将JSP文件转换成对应的Class类)。

验证

  • 这一阶段的主要目的是为了确保Class文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

准备

  • 准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。注意这里所说的初始值概念,比如一个类变量定义为: public static int v = 8080; 实际上变量v在准备阶段过后的初始值为0而不是8080,将v赋值为8080的putstatic指令是程序被编译后,存放于类构造器方法之中,这里我们后面会解释。 但是注意如果声明为: public static final int v = 8080; 在编译阶段会为v生成ConstantValue属性,在准备阶段虚拟机会根据ConstantValue属性将v赋值为8080。

解析

  • 解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。符号引用就是class文件中的: CONSTANT_Class_info CONSTANT_Field_info CONSTANT_Method_info 等类型的常量。

符号引用和直接引用的概念:

  • 符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。 直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。

初始化

  • 初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都由JVM主导。到了初始阶段,才开始真正执行类中定义的Java程序代码。 初始化阶段是执行类构造器 方法的过程。方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证方法执行之前,父类的方法已经执行完毕。p.s: 如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成()方法。

注意以下几种情况不会执行类初始化:

  • 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
  • 定义对象数组,不会触发该类的初始化。
  • 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
  • 通过类名获取Class对象,不会触发类的初始化。
  • 通过Class.forName加载指定类时,如果指定参数initialize为false时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。
  • 通过ClassLoader默认的loadClass方法,也不会触发初始化动作。

给你一个未知长度的链表,怎么找到中间的那个节点? 快慢指针,快指针走两步,慢指针走一步,快指针到尾了,慢指针走到一半。

类加载器 (*)

面试必考

虚拟机设计团队把加载动作放到JVM外部实现,以便让应用程序决定如何获取所需的类,JVM提供了3种类加载器:

  • 启动类加载器(Bootstrap ClassLoader):负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。
  • 扩展类加载器(Extension ClassLoader):负责加载 JAVA_HOME\lib\ext 目录中的,或通过java.ext.dirs系统变量指定路径中的类库。
  • 应用程序类加载器(Application ClassLoader):负责加载用户路径(classpath)上的类库。
  • JVM通过双亲委派模型进行类的加载,当然我们也可以通过继承java.lang.ClassLoader实现自定义的类加载器。
  • 当一个类加载器收到类加载任务,会先交给其父类加载器去完成,因此最终加载任务都会传递到顶层的启动类加载器,只有当父类加载器无法完成加载任务时,才会尝试执行加载任务。
  • 采用双亲委派的一个好处是比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个Object对象

访问权限

  • 对于外部类来说,只有两种修饰,public和默认(default),因为外部类放在包中,只有两种可能,包可见和包不可见。
  • 对于内部类来说,可以有所有的修饰,因为内部类放在外部类中,与成员变量的地位一致,所以有四种可能。

Spring bean 范围

  • singleton, prototype, request, session, global session

进程间的通信方式,线程间的通信方式 进程

  • 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
  • 有名管道 (namedpipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
  • 信号量(semophore ) :信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
  • 消息队列( messagequeue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 信号 (sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
  • 共享内存(shared memory ):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
  • 套接字(socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

线程

  • 锁机制:包括互斥锁、条件变量、读写锁
    • 互斥锁提供了以排他方式防止数据结构被并发修改的方法。
    • 读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
    • 条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。while+if+volatile变量
  • 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
  • 信号机制(Signal):类似进程间的信号处理

Java线程

  • synchoronized
  • wait/notify
  • lock condition
  • semaphore
  • countdownlatch
  • cyclicbarrier

线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

MyBatis中#{}和

代码语言:javascript
复制
不能识别此Latex公式:
{}区别(*)


#{}是经过预编译的,是安全的,而

{}是未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入。

  • 只能${}的情况,order by、like 语句只能用${}了,用#{}会多个' '导致sql语句失效.此外动态拼接sql也要用 不能识别此Latex公式: {}
  • #{} 这种取值是编译好SQL语句再取值, {} 这种是取值以后再去编译SQL语句

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的sql注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

数据库数据不一致的原因

  • 数据冗余

如果数据库中存在冗余数据,比如两张表中都存储了用户的地址,在用户的地址发生改变时,如果只更新了一张表中的数据,那么这两张表中就有了不一致的数据。

  • 并发控制不当

比如某个订票系统中,两个用户在同一时间订同一张票,如果并发控制不当,可能会导致一张票被两个用户预订的情况。当然这也与元数据的设计有关。

  • 故障和错误

如果软硬件发生故障造成数据丢失等情况,也可能引起数据不一致的情况。因此我们需要提供数据库维护和数据恢复的一些措施。

线程的状态(*)

笔试常考

  • 新建( new ):新创建了一个线程对象。
  • 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
  • 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
  • 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种: (一). 等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列(waitting queue )中。 (二). 同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。 (三). 其他阻塞: 运行( running )的线程执行Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM会把该线程置为阻塞. 当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
  • 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。

如何确保N个线程可以访问N个资源同时又不导致死锁?

多线程产生死锁需要四个条件,分别是互斥性,保持和请求,不可剥夺性还有要形成闭环,这四个条件缺一不可,只要破坏了其中一个条件就可以破坏死锁,其中最简单的方法就是线程都是以同样的顺序加锁和释放锁,也就是破坏了第四个条件。

背包问题(*) 试题描述:小明喜欢在火车旅行的时候用手机听音乐,他有N首歌在手机里,在整个火车途中,他可以听P首歌,所以他想产生一个播放表产生P首歌曲,这个播放表的原则是:

(1)每首歌都要至少被播放一次

(2)在两首一样的歌中间,至少有N首其他的歌

小明想有多少种不同的播放表可以产生,那么给你N、M、P,你来算一下,输出结果取1000000007的余数。

  • 定义 value(i,j) 为在背包装载体积为 i,物品为第 1 到 j 个的情况下,背包的最大价值 value(v,sum(m[i])) 即为所求 可以把空间复杂度从 O(nv) 降到 O(v) 状态转移方程: value(i,j) = |-> max(value(i-w[j],j-1)+s[j],value(i-1,j-1) (i-w[j] >= 0) |-> value(i-1,j-1) (i-w[j] < 0)

进程,线程区别

  • 1)含义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
  • 2)区别 (1)一个程序至少有一个进程,一个进程至少有一个线程. (2)线程的划分尺度小于进程,使得多线程程序的并发性高。 (3)进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 (4)线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 (5)从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。

int cast到byte(*) 笔试题

代码语言:javascript
复制
  public class leftshift_operator {
  public static void main(String args[]){



      byte x = 64;

      int i;

      byte y;

      i = x<<2;

      y = (byte)(x<<2);

      System.out.print(i+ " " +y);

  }
  }

CMS缺点

  • CMS收集器对CPU资源非常敏感 在并发阶段,虽然不会导致用户线程停顿,但是会因为占用了一部分线程使应用程序变慢,总吞吐量会降低,为了解决这种情况,虚拟机提供了一种“增量式并发收集器” 的CMS收集器变种, 就是在并发标记和并发清除的时候让GC线程和用户线程交替运行,尽量减少GC 线程独占资源的时间,这样整个垃圾收集的过程会变长,但是对用户程序的影响会减少。(效果不明显,不推荐)
  • CMS处理器无法处理浮动垃圾 CMS在并发清理阶段线程还在运行, 伴随着程序的运行自然也会产生新的垃圾,这一部分垃圾产生在标记过程之后,CMS无法再当次过程中处理,所以只有等到下次gc时候在清理掉,这一部分垃圾就称作“浮动垃圾”
  • CMS是基于“标记--清除”算法实现的,所以在收集结束的时候会有大量的空间碎片产生。空间碎片太多的时候,将会给大对象的分配带来很大的麻烦,往往会出现老年代还有很大的空间剩余,但是无法找到足够大的连续空间来分配当前对象的,只能提前触发full gc。
  • 需要更大的堆空间

++操作符和乘除 下列代码执行后的变量num3的值?

代码语言:javascript
复制
public static void main(String[] args) {  
int num1 = 6, num2 = 7, num3 = 12;  

if (++num1 == num2)  
    num3 = ++num3 * 3;  
System.out.println(num3);
}  

某网络的IP地址空间为10.0.17.0/24,采用等长子网划分,子网掩码为255.255.255.240,则该网络的最大子网个数、每个子网内的最大分配地址个数?(*) 笔试常考

  • 240, 11110000
  • 2^4=16 最大子网个数
  • 2^4-2=14 子网最大分配地址个数

Class, newInstance, 默认构造器

代码语言:javascript
复制
public class whatTheHell {  
public whatTheHell() {  
}  

private String a;  
private Integer b;  

public whatTheHell(String a, Integer b) {  
    this.a = a;  
    this.b = b;  
}  

public String getA() {  

    return a;  
}  

public void setA(String a) {  
    this.a = a;  
}  

public Integer getB() {  
    return b;  
}  

public void setB(Integer b) {  
    this.b = b;  
}  

public static void main(String[] args) {  
    Class<whatTheHell> whatTheHellClass = whatTheHell.class;  
    try {  
        whatTheHell whatTheHell = whatTheHellClass.newInstance();  
        System.out.println(whatTheHell == null ? true : false);  
    } catch (InstantiationException e) {  
        e.printStackTrace();  
    } catch (IllegalAccessException e) {  
        e.printStackTrace();  
    }  

}
}  

若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别0和3。当从队列中删除一个元素,再加入两 个元素后,rear和front的值分别为?

  • 2,4
  • 删除一个元素后,队首指针要加1,front=(front+1)%6,结果为4,每加入一个元素队尾指针加一,即real=(real+1)%6,加入两个元素后变为2

棵完全二叉树有600个节点,那么它的叶子节点有

  • (600+1)/2=300

this, super

  • this()函数主要应用于同一类中从某个构造函数调用另一个重载版的构造函数。this()只能用在构造函数中,并且也只能在第一行。所以在同一个构造函数中this()和super()不能同时出现。
  • super()函数在子类构造函数中调用父类的构造函数时使用,而且必须要在构造函数的第一行

java中,当实例化子类对象时,如果有以下几个会被加载,那么加载的顺序是什么?(*) 笔试常考

  • (1)父类静态代码块
  • (2)子类静态代码块
  • (3)父类非静态代码块
  • (4)父类构造函数
  • (5)子类非静态代码块
  • (6)子类构造函数

设在一棵度数为3的树中,度数为3的结点数有2个,度数为2的结点数有1个,度数为1的结点数有2个,那么度数为0的结点数有( )个?

  • 顶点数 = 所有节点度数 +1
  • 2+1+2+x = (3x2 + 2x1 + 1x2 + 0 x X) + 1
  • x = 6

forward和redirect区别

  • 直接转发方式(Forward),客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
  • 间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。
  • redirect 默认302暂时跳转

操作系统,临时抱佛脚

  • https://blog.csdn.net/csdn_chai/article/details/78002202
  • https://zhuanlan.zhihu.com/p/23755202

前缀(波兰),后缀(逆波兰),中缀表达式

  • https://blog.csdn.net/antineutrino/article/details/6763722

BigInteger, BigDecimal

  • https://blog.csdn.net/zhongkelee/article/details/52289163

在一个C类地址段内,需要将网络划分为 7个子网,每个子网有15个主机,则可以使用哪个子网掩码?(*)

  • 255.255.255.224
  • IP地址的结构是:网络号+主机号, 划分子网是从主机号中抽取几位进行子网划分,c类地址前24位为网络号
  • 224, 11100000
  • 2^3=8>7
  • 2^5=32>15

Linux 网络相关命令

  • ping是使用的ICMP协议,是IP层协议,但是端口是应用层的,所以它只能判断能够访问ip,不能判断端口
  • ifconfig是查看本机的网络设置,IP,子网掩码等
  • telnet是应用层的,可以判端口访问情况
  • netstat显示网络信息,如网络连接,路由表,接口状态

递归时间复杂度 master 公式 T(N) = a*T(N/b) + O(N^d)

估计递归问题复杂度的通式,只要复杂度符合以下公式,都可以套用此公式计算时间复杂度

例子:递归方式查找数组最大值 T(N) = 2*T(N/2) + O(1)

T(N):样本量为 N 的情况下,时间复杂度 N:父问题的样本量 a:子问题发生的次数(父问题被拆分成了几个子问题,不需要考虑递归调用,只考虑单层的父子关系) b:被拆成子问题,子问题的样本量(子问题所需要处理的样本量),比如 N 被拆分成两半,所以子问题样本量为 N/2 O(N^d):剩余操作的时间复杂度,除去调用子过程之外,剩下问题所需要的代价(常规操作则为 O(1))

  • log(b,a) > d -> 复杂度为O(N^log(b,a))
  • log(b,a) = d -> 复杂度为O(N^d * logN)
  • log(b,a) < d -> 复杂度为O(N^d)

Java变量命名(*)

  • $, _, 字母开头
  • 不能是数字开头
  • 不能使关键字private, final…

查看linux操作系统磁盘空间命令

  • df

设有一个含有13个元素的Hash表(0~12),Hash函数是:H(key)=key % 13,其中%是求余数运算。用线性探查法解决冲突,则对于序列(2、8、31、20、19、18、53、27),18应放在第几号格中?

  • 求出18之前的序列余数为2、8、5、7、6,H(18)=5与之前的冲突,直接向后移,6、7、8都有元素,因此放在9号上

如果一个二叉树中任意节点的左右子树“高度”相差不超过 1,我们称这个二叉树为“高度平衡二叉树”。根据如上定义,一个高度为 8 的高度平衡二叉树至少有几个节点?

  • 54
  • 类似斐波那契数列的递推公式。Sn = Sn-1 + Sn-2 + 1,初值,S1 =1,S2 =2
  • 1 2 4 7 12 20 33 54

某公司申请到一个C类IP地址,但要连接6个的子公司,最大的一个子公司有 26台计算机,每个子公司在一个网段中,则子网掩码应设为?(*)

  • 11111111.11111111.11111111.?
  • 2^3=8, 至少3个1
  • 2^5=32, 32-网关-广播=30>26
  • 11100000
  • 224
  • 255.255.255.224

END

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员乔戈里 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档