又逢金九银十,意味着很多人又面临着就职和跳槽,相信还有很多人对于自己就职没有很大的把我,今天就给大家分享我一个朋友总结的4000到Java必问核心知识点,以及面试真题解答。
(基础知识)
什么是SMTP?
SMTP全称为Simple Mail Transfer Protocol(简单邮件传输协议),它是⼀组⽤于从源地址到⽬的地址传输邮件的规范,通过它来控制邮件的中转⽅式。SMTP认证要求必须提供账号和密码才能登陆服务器,其设计⽬的在于避免⽤⼾受到垃圾邮件的侵扰.
什么是IMAP?
IMAP全称为Internet Message Access Protocol(互联⽹邮件访问协议),IMAP允许从邮件服务器上获取邮件的信息、下载邮件等。IMAP与POP类似,都是⼀种邮件获取协议。
什么是POP3?
POP3全称为Post Office Protocol 3(邮局协议),POP3⽀持客⼾端远程管理服务器端的邮件。POP3常⽤于“离线”邮件处理,即允许客⼾端下载服务器邮件,然后服务器上的邮件将会被删除。⽬前很多POP3的邮件服务器只提供下载邮件功能,服务器本⾝并不删除邮件,这种属于改进版的POP3协议。
IMAP和POP3协议有什么不同呢?
两者最⼤的区别在于,IMAP允许双向通信,即在客⼾端的操作会反馈到服务器上,例如在客⼾端收取邮件、标记已读等操作,服务器会跟着同步这些操作。⽽对于POP协议虽然也允许客⼾端下载服务器邮件,但是在客⼾端的操作并不会同步到服务器上⾯的,例如在客⼾端收取或标记已读邮件,服务器不会同步这些操作。
(进阶知识)
什么是javamailsender和 javamailsenderlmpl?
JavaMailSender和JavaMailSenderImpl 是Spring官⽅提供的集成邮件服务的接⼝和实现类,以简单⾼效的设计著称,⽬前是Java后端发送邮件和集成邮件服务的主流⼯具。
如何通过 javamailsenderlmpl发送邮件?
⾮常简单,直接在业务类注⼊JavaMailSenderImpl并调⽤send⽅法发送邮件。其中简单邮件可以通过SimpleMailMessage来发送邮件,⽽复杂的邮件(例如添加附件)可以借助MimeMessageHelper来构建MimeMessage发送邮件。例如:
为什么javamailsenderlmpl能够开箱即用?
所谓开箱即⽤其实就是基于官⽅内置的⾃动配置,翻看源码可知晓邮件⾃动配置类(MailSenderPropertiesConfiguration) 为上下⽂提供了邮件服务实例(JavaMailSenderImpl)。具体源码如下:
其中MailProperties是关于邮件服务器的配置信息,具体源码如下:
(1)Netflix Eureka
1)、Eureka服务端:也称服务注册中⼼,同其他服务注册中⼼⼀样,⽀持⾼可⽤配置。如果Eureka以集群模式部署,当集群中有分⽚出现故障时,那么Eureka就转⼊⾃我保护模式。它允许在分⽚故障期间继续提供服务的发现和注册,当故障分⽚恢复运⾏时,集群中其他分⽚会把它们的状态再次同步回来
2)、Eureka客⼾端:主要处理服务的注册与发现。客⼾端服务通过注解和参数配置的⽅式,嵌⼊在客⼾端应⽤程序的代码中,在应⽤程序运⾏时,Eureka客⼾端想注册中⼼注册⾃⾝提供的服务并周期性地发送⼼跳来更新它的服务租约。同时,它也能从服务端查询当前注册的服务信息并把它们缓存到本地并周期性地刷新服务状态
3)、Eureka Server的⾼可⽤实际上就是将⾃⼰作为服务向其他注册中⼼注册⾃⼰,这样就可以形成⼀组互相注册的服务注册中⼼,以实现服务清单的互相同步,达到⾼可⽤效果
(2)Eureka详解
zookeeper,其实很早就计划写关于它的⽂章,但是由于各种原因⼀直推到了今天。本⽂会以类⽐的⽅式循序渐进、层层展开。各位坐稳了,让我们开启⼀段⼤脑的旅程。
边界的产生与突破:
不觉间孩⼦已经上⼩学了,前段时间还参加了⼀次家⻓会,那就以学校和开会来说吧,这⼤家都很熟悉。
如果⼀个班要想开班会,那随时开都⾏,不需要提前安排与通知,因为⼀个班级从内部看就是⼀个整体,在班级内,
同学之间以及与⽼师之间都可以随意交流,没有任何隔阂与阻碍。
⼀个班级从外部看就是⼀个独⽴的个体,因为班级与班级之间是完全独⽴的,因此⼀个班级的学⽣和⽼师都不会随便跑到其它班级去。这是因为存在着⼀个边界,即班级边界。
正是这个班级边界把班级隔开了,边界之内的事情,如班会,可以随便开展,因为它和边界之外的⼀切都⽆关。但是⼀旦涉及到边界之外,也就是跨边界,那么问题就产⽣了。
⽐如学校要开⼀个全体班级⼤会,肯定会提前安排好时间地点,以及各个班级在操场上的排列顺序,还要提前进⾏相应的通知。
为什么⼀个班的班会可以随时随地进⾏,⽽全体班级⼤会就要提前安排与通知呢?就是因为它跨了班级边界,是⼀个跨边界问题。
⽽且班级与班级之间互相独⽴,互相不太熟悉,可能沟通起来也不容易,因此需要提前安排好。
那如何通知呢?可以让班级之间互相通知,如⼀班通知⼆班,⼆班通知三班等等。也可以由⼀个独⽴于所有班级之外的⼈,如教务处或学⽣处的⼈,来依次通知所有班级。
这两种通知⽅法在现实中都有使⽤,所有没有绝对的好与坏之分,视情况⽽定即可。
计算机相关的边界产生与突破
上⼀⼩节的描述⾮常简单,相信所有⼈都能明⽩。接着就来说说和计算机相关的边界。其实有很多,我们就说⼀两种吧。
操作系统⾥⾯有内核空间和⽤⼾空间,它们之间是有边界的,但是它们之间依然是可以交流的,因为操作系统的开发者已经做好了交流的⽅式⽅法。
每个应⽤程序通常都是⼀个进程,由于应⽤之间通常差别较⼤,⽽且还有⼀些其它⽅⾯的考虑,如安全问题,所以进程之间是有边界的,即进程边界。
操作系统是按进程分配资源的,因此⼀个进程内部的线程共享这些资源。由于进程边界的存在,这些资源不能被别的进程使⽤。所以进程就像是⼀个班级。
由于不同进⾏之间通常不需要交流,就像班级之间通常也不怎么交流⼀样,所以默认情况下进程之间⽆法交流,这与操作系统的内核和⽤⼾空间是不同的。
但总归有特殊情况吧,如果进程间需要交流怎么办?那只能由开发⼈员⾃⼰想办法,如通过Socket,来实现。这种情况在中间件⾥很常⻅,如Nginx就涉及多个进程。
因为中间件的开发者⼀般都是⽜X的⼈,他们能够搞定。但问题是绝⼤多数开发⼈员都是搞业务开发的,他们受能⼒、时间或⾦钱限制,往往做不出来⽣产级别的交流⽅法。
可是有时候业务⼈员开发的应⽤程序的进程之间也是需要交流的,就像要开全体班级⼤会那样,我们可以类⽐着来寻求解决⽅案。
我们可以让进程之间直接互相交流,就像班级之间互相通知那样,这⼀⽅⾯对开发⼈员要求⾼且费时费⼒,另⼀⽅⾯是当进程多了之后,它们之间的直接交流就变成了⼀张⽹,会很乱。
为了说明这⼀点,我们看个简单⽰例。假如张三、李四、王五是同事,周五下午下班时互相穿错了⾐服,遗憾的是晚上回到家后才发现。他们都想在第⼆天,就是周六,换过来。
张三需要去找李四,李四需要去找王五,王五⼜需要去找张三,假设他们都住的相距较远,这会是⼀个颇为复杂的问题。那么如果有20个⼈都互相穿错了⾐服呢,这将会是⼀个更加复杂的问题。
可以看出,如果个体之间互相直接交流的话,随着个体数⽬的增多,将会变得⽆⽐混乱与复杂。⽐较好的解决⽅法可能⼤家都想到了。
那就是约定⼀个合适的地⽅,如公司,张三、李四、王五都过去,互相交换完⾐服后各⾃回家。这种⽅法随着个体的增多效果会越来越好
本篇内容主要讲解的是redis分布式锁,这个在各⼤⼚⾯试⼏乎都是必备的,下⾯结合模拟抢单的场景来使⽤她;本篇不涉及到的redis环境搭建,快速搭建个⼈测试环境,这⾥建议使⽤docker;本篇内容节点如下:
jedis的nx生成锁:
对于java中想操作redis,好的⽅式是使⽤jedis,⾸先pom中引⼊依赖:
对于分布式锁的⽣成通常需要注意如下⼏个⽅⾯:
创建锁的策略:redis的普通key⼀般都允许覆盖,A⽤⼾set某个key后,B在set相同的key时同样能成功,如果是锁场景,那就⽆法知道到底是哪个⽤⼾set成功的;这⾥jedis的setnx⽅式为我们解决了这个问题,简单原理是:当A⽤⼾先set成功了,那B⽤⼾set的时候就返回失败,满⾜了某个时间点只允许⼀个⽤⼾拿到锁。
锁过期时间:某个抢购场景时候,如果没有过期的概念,当A⽤⼾⽣成了锁,但是后⾯的流程被阻塞了⼀直⽆法释放锁,那其他⽤⼾此时获取锁就会⼀直失败,⽆法完成抢购的活动;当然正常情况⼀般都不会阻塞,A⽤⼾流程会正常释放锁;过期时间只是为了更有保障。
下⾯来上段setnx操作的代码:
这⾥注意点在于jedis的set⽅法,其参数的说明如:
整个4000道Java面试真题合集,就在这里给大家展示了一部分,还有包括spring全家桶,MyBatis.,Nginx.Java集合.等等专题。还包括有大厂的面试真题,没有在这里一一给大家展示,大家有需要的可以点击获取资料获取资料。