Redis是如何实现list存储的
List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样 ,我们可以在其头部(lf)和尾部(right)添加新的元素。
在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。
SpringMVC的优势、基本原理以及大概的流程
springmvc是一个轻量级IOC容器框架,拥有一致的事务管理和面向切面工程。
1.和Spring其他框架无缝结合,是其他web框架所不具备的
2.可适配,通过HandlerAdapter可以支持任意的类作为处理器
3.利用Spring提供的Mock对象能够非常简单的进行Web层单元测试;
4.强大的JSP标签库,使Jsp编写更容易。
①. Springmvc将所有的请求都提交给 中央调度器Dispatcherservlet
②. Dispatcherservlet收到请求调用 Handl ermapping处理映射器
③.处理映射器找到具体的处理器,生成处理器对象返回给 Dispatcherservlet
④. Dispatcherservlet调用 Handl eradapter处理器适配器
⑤. Handl eradapter经过适配调用具体的处理器 Controller
6. Controller进行业务逻辑处理后,会返回一个 Modelandview
⑦. Handl eradapter将 Controller执行结果 Modelandview返回给 Dispatcherservlet
⑧. Dispatcherservlet将 Modelandview传给Viewresolver视图解析器
⑨. Viewresolver解析后返回具体的View
⑩ Dispatcherservlet根据View进行渲染视图并响应用户
JSP和servlet 的区别
(1).jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
(2).jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
(3).Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象, HttpServletResponse对象以及HttpServlet对象得到.
Java中是 怎么解析xml的
(1) DOM(JAXP Crimson解析器)
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。
由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。
(2)SAX
SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。
(3)JDOM
JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。
(4)DOM4J
它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。
MySQL数据库的索引有哪几种?有什么区别?
(1)普通索引。最基本的索引,它没有任何限制,用于加速查询。
(2)唯一索引。索引列的值必须唯一,但允许有空值。
(3)主键索引。是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般 是在建表的时候同时创建主键索引。
(4)组合索引。指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。
(5)全文索引。主要用来查找文本中的关键字,而不是直接与索引中的值相比较。
class.forName是什么意思
返回与给定的字符串名称相关联类或接口的Class对象。
是一个静 态方法,同样可以用来加载类。该方法有两种形式:Class.forName(String name, boolean initialize, ClassLoader loader)和 Class.forName(String className)。
第一种形式的参数 name表示的是类的全名;initialize表示是否初始化类;loader表示加载时使用的类加载器。
第 二种形式则相当于设置了参数 initialize的值为 true,loader的值为当前类的类加载器。
几种造线程池的方法,区别 ?
(1)newFixedThreadPool
定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
(2)newCachedThreadPool
可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
(3)newScheduledThreadPool
定长线程池,可执行周期性的任务
(4)newSingleThreadExecutor
单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
(5)newSingleThreadScheduledExecutor
单线程可执行周期性任务的线程池
(6)newWorkStealingPool
任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。默认创建的并行 level 是 CPU 的核数。主线程结束,即使线程池有任务也会立即停止。
面向服务通过什么样的方式实现?
面向服务(SOP)是一种体系结构,目标是在软件代理交互中获得松散耦合。一个服务是一个服务提供者为一个服务消费者获得其想要的最终结果的一个工作单元。
Web Service是面向服务编程的方式之一
https://blog.csdn.net/hu_zhiting/article/details/50594633
原理:
(1)Web Service采用SOAP协议实现跨编程语言和跨操作系统平台。
(2)Web Service采用HTTP协议传输数据,采用XML格式封装数据(即说明调用什么方法,传递什么参数,返回结果是什么)。
(3)Web Service通过HTTP协议发送请求和接收结果时,发送的请求内容和结果都采用XML格式封装,并增加一些特定的HTTP消息头,说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式便是SOAP协议(即HTTP协议+XML数据格式)。
消息中间件 acitveMQ 的作用、原理?几种模式,每种的特点及使用问题?MQ 发送消息失败怎么办?
作用:消除高并发访问高峰,加快网站的响应速度。
消息中间件的两种消息传递模式
(1)点对点消息通信型:也称为队列模式,一条特定的消息只给一个特定的消费者,消费完成之后就从持久化存储中删除该数据,生产者将消息发送到指定的队列(queue)中,此时对于消费者来说,获取消息有两种方式.分别是pull和push,其中push方式是activeMQ接收到消息之后去调用消费者的新消息通知接口,相当于activeMQ去通知消费者,但是这样会浪费activeMQ的宝贵线程资源.而pull方式,是消费者循环调用activeMQ的api去获取消息,这样不会消耗activeMQ的线程资源,并且消费者更加主动.push方式由于过多占用activeMQ的线程资源而难以应对高并发,所以并不适用.
(2)发布/订阅模式:也称为主题模式,特定的一条消息可以被多个消费者接收,只要消费者订阅了某个主题.消息的生产者会将消息发布到名称为topic的虚拟通道里面去,topic是可以被多个消费者订阅的.这个模式类似于广播模式,但是要求消费者在线监听,如果消费者离线,再次上线是无法获取该消息的,发布/订阅模式采用的是pull方式把消息发送给消费者.
Tomcat 集群中怎么实现共享
(1) 请求精确定位
例如基于访问IP地址的Hash策略,即当前用户的请求都集中定位到一台服务器中,这样单台服务器就会保存用户的Session登录信息。
但是如果宕机,则等同于单点故障,保存用户的Session登录信息就会丢失,会话不复制。
(2) Session复制共享
例如Tomcat自带Session共享,主要是指集群环境下多台应用服务器之间同步Session,使Session保持一致,对外则是保持透明。
如果其中一台服务器发生故障,根据负载均衡的原理,调度器会遍历寻找可用节点来分发请求。由于Session已同步,所以能够保证用户的Session信息不会丢失,也就是所谓的会话复制。
在数据库怎么复制表数据和表结构?
(1)复制表结构及数据到新表
CREATE TABLE 新表 SELECT * FROM 旧表
(2)只复制表结构到新表
CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2或CREATE TABLE 新表 LIKE 旧表
(3)复制旧表的数据到新表(假设两个表结构一样)
INSERT INTO 新表 SELECT * FROM 旧表
(4)复制旧表的数据到新表(假设两个表结构不一样)
INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 旧表
From表单提交的方法、属性,数据量大的时候用什么方法提交?
GET
提交的数据格式跟元素的method属性有关。该属性指定了提交数据的 HTTP 方法。
如果是 GET 方法,所有键值对会以 URL 的查询字符串形式,提交到服务器,比如/handling-page?user_name=张三&user_passwd=123&submit_button=提交。
POST
如果是 POST 方法,所有键值对会连接成一行,作为 HTTP 请求的数据体发送到服务器,比如user_name=张三&user_passwd=123&submit_button=提交。
FormData(XMLHttpRequest.sendf方法)
表单数据以键值对的形式向服务器发送,这个过程是浏览器自动完成的。但是有时候,我们希望通过脚本完成过程,构造和编辑表单键值对,然后通过XMLHttpRequest.send()方法发送。浏览器原生提供了 FormData 对象来完成这项工作。
数据量大
在form中添加属性enctype="multipart/form-data"使用文件上传的方式,不过这样后台取表单数据的方法就需要修改.
只能循环fileItemList去取出表单数据.
- Java多线程中哪种方式不会使线程进入阻塞状态
yield会是线程进入就绪状态
- shiro的工作流程?怎么认证?怎么授权?
(1)从shiro中获取subject主体
SecurityUtils.getSubject();
(2)判断当前用户是否认证过了,如果认证过了就放行了
subject.isAuthenticated()
(3)如果没有认证过,就把前台传递的账号密码封装为一个UserNamePasswordToken对象,
new UsernamePasswordToken(username, password);
(4)把UserNamePasswordToken对象传入,进行登录操作
subject.login(usernamepasswordtoken);
(5)我们配置的安全管理器中实现了doGetAuthenticationInfo方法,从数据库查询用户数据,加密加盐后进行shiro的认证
(6)如果认证成功,进行权限赋于。
(7)根据配置shiro的真实过滤器跳转至登录成功页面或登录失败的页面。
认证过程
授权
服务器宕机如何处理?全部宕机如何处理?
服务器宕机
(1)对于服务器频繁出现宕机情况就要注意了检查服务器是否存在负载量过大,服务器散热存在问题等等情况。再针对这样的情况一项一项来解决,这样才能保证服务器尽可能长时间正常运 行。
(2)对于一般服务器宕机,我们可以采用重启服务器的方式来解决。正常重启服务器可以清除内存碎片,重新优化应用软件,中断无用的端口,缓解CPU压力,加快服务器运行速度等等。
(3)对于服务器租用用户来说,服务器宕机是非常值得重视的问题,如果租用的服务器经常出现宕机情况的话,一定要及时通知服务商,让服务器查明具体情况,问题过于严重甚至可以要求跟换服务器或者更换服务器供应商。
做好防范准备。可以同时运行两个网站空间,存放相同的内容,当一个出现问题时,立即启用另一个即可。
java多线程有几种实现方法?都是什么?它们的区别?
两种
继承 Thread 类:多个任务由多个线程来完成,互相不干扰,各玩各的,多个线程分别完成自己的任务
实现 Runnable 接口:一个任务由多个线程来共同完成
具体实现如下:
多个线程输出https://blog.csdn.net/kanglix1an/article/details/46006093
JDO是 什么?说说你 对JDO的 理解
JDO是Java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)。JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。
如何在Jsp中把div或table隐藏起来?
Table的隐藏
<script> function show(){ var myTable= document.getElementById("myTable"); myTable.style.display="block"; } function hidden(){ var myTable= document.getElementById('myTable); myTable.style.display ="none"; } </script> <input type="button" name="button" value="显示" onclick="show()"> <input type="button" name="button" value="隐藏" onclick="hidden()"> <table width="200" id="myTable" border="0" align="center" cellpadding="1" cellspacing="0" style="display: none"> <tr><td height="60" align="center" class="hong12">显示table信息</td></tr> </table>
Div的隐藏
1.display:none;
2.visibility:hidden;
TCP和UDP的区别?
TCP 是面向连接的,UDP 是面向无连接的
UDP程序结构较简单
TCP 是面向字节流的,UDP 是基于数据报的
TCP 保证数据正确性,UDP 可能丢包
TCP 保证数据顺序,UDP 不保证
Servelet在多个请求时存在线程安全问题,请讲一下在servelet编程中要注意什么问题?
(1)实现 SingleThreadModel 接口
确保servlet每次只处理一项请求。接口不含方法。
如果servlet实现了该接口,会确保不会有两个线程同时执行servlet的service方法。 servlet容器通过同步化访问servlet的单实例来保证,也可以通过维持servlet的实例池,对于新的请求会分配给一个空闲的servlet。
(2)同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中的Servlet可以通过同步块操作来保证线程的安全。
(3)避免使用实例变量
只要在Servlet里面的任何方法里面都不使用实例变量,那么该Servlet就是线程安全的。
小结
Servlet的线程安全问题只有在大量的并发访问时才会显现出来,并且很难发现,因此在编写Servlet程序时要特别注意。
Quartz怎么配置啊?
Quartz有三要素:
Scheduler:调度器。所有的调度都是由它控制。
Trigger: 定义触发的条件。例子中,它的类型是SimpleTrigger,每隔1秒中执行一次(什么是SimpleTrigger下面会有详述)。
JobDetail & Job: JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中,例子中是HelloQuartz。 为什么设计成JobDetail + Job,不直接使用Job?这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。
服务器集群和session的同步方法及优点?
(1)客户端cookie加密
简单,高效。比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现。
问题:session中数据不能太多,最好只有个用户id。
(2) application server的session复制
可能大部分应用服务器都提供了session复制的功能来实现集群,tomcat,jboss,was都提供了这样的功能。
问题:
性能随着服务器增加急剧下降,而且容易引起广播风暴;
session数据需要序列化,影响性能。
(3)使用数据库保存session
使用数据库来保存session,就算服务器宕机了也没事,session照样在。
问题:
程序需要定制;
每次请求都进行数据库读写开销不小(使用内存数据库可以提高性能,宕机就会丢失数据。可供选择的内存数据库有BerkeleyDB,MySQL的内存表);
数据库是一个单点,当然可以做数据库的ha来解决这个问题。
(5)使用共享存储来保存session
和数据库类似,就算服务器宕机了也没事,session照样在。使用nfs或windows文件共享都可以,或者专用的共享存储设备。
问题:
程序需要定制;
频繁的进行数据的序列化和反序列化,性能是否有影响;
共享存储是一个单点,这个可以通过raid来解决。
(5)使用memcached来保存session
这种方式跟数据库类似,不过因为是内存存取的,性能自然要比数据库好多了。
问题:
程序需要定制,增加了工作量;
存入memcached中的数据都需要序列化,效率较低;
memcached服务器一死,所有session全丢。
(6)使用terracotta来保存session
跟memcached类似,但是数据不需要序列化,并且是Find-Grained Changes,性能更好。
配置对原来的应用完全透明,原有程序几乎不用做任何修改。而且terracotta本身支持HA。
tomcat端口(当一台电脑上有两个tomcat 端口一样 怎么去修改 让两个tomcat一起运行)
当第一个tomcat启动后,后面tomcat的server.xml中的端口不管怎么改,仍然会报端口冲突。后来在dos下运行才发现所有的tomcat都会去找CATALINA_HOME和CATALINA_BASE这两个环境变量,因此步骤如下:
(1)使用压缩版的tomcat不能使用安装版的。
(2)第一个tomcat的配置不变。
(3)增加环境变量CATALINA_HOME2,值为新的tomcat的地址;增加环境变量CATALINA_BASE2,值为新的tomcat的地址。
(4)修改新的tomcat中的startup.bat,把其中的CATALINA_HOME改为CATALINA_HOME2。
(5)修改新的tomcat中的catalina.bat,把其中的CATALINA_HOME改为CATALINA_HOME2,CATALINA_BASE改为CATALINA_BASE2。
(6)修改conf/server.xml文件:
6.1 <Server port="8005" shutdown="SHUTDOWN">把端口改为没有是使用的端口。
6.2 <Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" /> 把端口改为没有是使用的端口。
6.3<Connector port="8009"
enableLookups="false" redirectPort="8443" protocol="AJP/1.3" /> 把端口改为没有是使用的端口。
(7)成功!
Linux的基本命令
ls 显示文件夹
cd 进入目录
mkdir 创建文件夹
rm 删除文件或目录
https://www.cnblogs.com/huangting/p/11510852.html
线程池使用过哪些?原理是什么?
CachedThreadPool
这类线程池的特点就是里面没有核心线程,全是非核心线程,其maximumPoolSize设置为Integer.MAX_VALUE,线程可以无限创建,当线程池中的线程都处于活动状态的时候,线程池会创建新的线程来处理新任务,否则会用空闲的线程来处理新任务,这类线程池的空闲线程都是有超时机制的,keepAliveTime在这里是有效的,时长为60秒,超过60秒的空闲线程就会被回收,当线程池都处于闲置状态时,线程池中的线程都会因为超时而被回收,所以几乎不会占用什么系统资源。任务队列采用的是SynchronousQueue,这个队列是无法插入任务的,一有任务立即执行,所以CachedThreadPool比较适合任务量大但耗时少的任务。
FixedThreadPool
这类线程池的特点就是里面全是核心线程,没有非核心线程,也没有超时机制,任务大小也是没有限制的,数量固定,即使是空闲状态,线程不会被回收,除非线程池被关闭,从构造方法也可以看出来,只有两个参数,一个是指定的核心线程数,一个是线程工厂,keepAliveTime无效。任务队列采用了无界的阻塞队列LinkedBlockingQueue,执行execute方法的时候,运行的线程没有达到corePoolSize就创建核心线程执行任务,否则就阻塞在任务队列中,有空闲线程的时候去取任务执行。由于该线程池线程数固定,且不被回收,线程与线程池的生命周期同步,所以适用于任务量比较固定但耗时长的任务。
ScheduledThreadPool
这类线程池核心线程数量是固定的,好像和FixThreadPool有点像,但是它的非核心线程是没有限制的,并且非核心线程一闲置就会被回收,keepAliveTime同样无效,因为核心线程是不会回收的,当运行的线程数没有达到corePoolSize的时候,就新建线程去DelayedWorkQueue中取ScheduledFutureTask然后才去执行任务,否则就把任务添加到DelayedWorkQueue,DelayedWorkQueue会将任务排序,按新建一个非核心线程顺序执行,执行完线程就回收,然后循环。任务队列采用的DelayedWorkQueue是个无界的队列,延时执行队列任务。综合来说,这类线程池适用于执行定时任务和具体固定周期的重复任务。
SingleThreadPool
这类线程池顾名思义就是一个只有一个核心线程的线程池,从构造方法来看,它可以单独执行,也可以与周期线程池结合用。其任务队列是LinkedBlockingQueue,这是个无界的阻塞队列,因为线程池里只有一个线程,就确保所有的任务都在同一个线程中顺序执行,这样就不需要处理线程同步的问题。这类线程池适用于多个任务顺序执行的场景。
https://www.cnblogs.com/zzuli/p/9386463.html
你最常用的设计模式是什么?优缺点?
单例模式:保证被创建一次,节省系统开销。
工厂模式(简单工厂、抽象工厂):解耦代码。
观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
shiro是什么?shiro用来干什么的?shiro怎么用的?
Shiro是一个非常强大的、易于使用的、开源的、权限框架。它包括了权限校验、权限授予、会话管理、安全加密等组件。
Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。这不就是我们想要的嘛,而且 Shiro 的 API 也是非常简单
(注意:记住一点,Shiro 不会去维护用户、维护权限;这些需要我们自己去设计 / 提供;然后通过相应的接口注入给 Shiro 即可)
Shiro使用步骤。
1.先把账号密码传入Shiro里面的UsernamePasswordToken对象里面。
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
2.创建Subject对象。
Subject subject = SecurityUtils.getSubject();
3.调用 Subject.login()进行登录,如果失败将得到相应的 AuthenticationException 异常,根据异常提示用户错误信息;否则登录成功。
try{ Subject.login(token)//调用安全管理器,安全管理器调用自定义Realm User user = (User) subject.getPrincipal();//登陆成功后就可以通过安全管理器获得用户对象。 }catch (UnknownAccountException e) { error = "用户名/密码错误"; } catch (IncorrectCredentialsException e) { error = "用户名/密码错误"; } catch (ExcessiveAttemptsException e) { // TODO: handle exception error = "登录失败多次,账户锁定10分钟"; } catch (AuthenticationException e) { // 其他错误,比如锁定,如果想单独处理请单独catch处理 error = "其他错误:" + e.getMessage(); } if (error != null) {// 出错了,返回登录页面 request.setAttribute("error", error); return "failure"; } else {// 登录成功 return "success"; }
4.最后调用 Subject.logout 进行退出操作
5.自定义Realm去写登陆的判断
public class UserRealm extends AuthorizingRealm { private UserService userService = new UserServiceImpl(); protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//用户授权 String username = (String)principals.getPrimaryPrincipal();//获取用户名 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.setRoles(userService.findRoles(username)); authorizationInfo.setStringPermissions(userService.findPermissions(username));//根据用户名查询权限集合 return authorizationInfo; } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {//用户认证 String username = (String)token.getPrincipal(); User user = userService.findByUsername(username); if(user == null) { throw new UnknownAccountException();//没找到帐号 } if(Boolean.TRUE.equals(user.getLocked())) { throw new LockedAccountException(); //帐号锁定 } //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以在此判断或自定义实现 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user.getUsername(), //用户名 user.getPassword(), //密码 ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt this.getClass().getName() //realm name ); return authenticationInfo; } }
tomcat 与 nginx,apache的区别是什么?Nginx和Apache各有什么优缺点?
(1)Apache
Apache HTTP服务器是一个模块化的服务器,可以运行在几乎所有广泛使用的计算机平台上。其属于应用服务器。Apache支持支持模块多,性能稳定,Apache本身是静态解析,适合静态HTML、图片等,但可以通过扩展脚本、模块等支持动态页面等。
(Apche可以支持PHP ,cgi(外部应用程序与Web服务器之间的接口), perl,但是要使用Java的话,你需要Tomcat在Apache后台支撑,将Java请求由Apache转发给Tomcat处理。) 缺点:配置相对复杂,自身不支持动态页面。
(2)Tomcat:
Tomcat是应用(Java)服务器,它只是一个Servlet(JSP也翻译成Servlet)容器(这里什么是Servlet和JSP可以参考后续文章),可以认为是Apache的扩展,但是可以独立于Apache运行。
(3) Nginx
Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”,是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP (这三个是什么可以参考我的这篇文章https://www.cnblogs.com/qingbaizhinian/p/12267869.html )代理服务器。
Nginx和Apache两者优缺点比较
Nginx 配置简洁, Apache 复杂 ;
Nginx 静态处理性能比 Apache 高 3倍以上 ;
Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端用;Apache 的组件比 Nginx 多
apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程;
nginx处理静态文件好,耗费内存少;
动态请求由apache去做,nginx只适合静态和反向;
Nginx适合做前端服务器,负载性能很好;
Nginx本身就是一个反向代理服务器 ,且支持负载均衡
mysql性能优化举例
(1)选择正确的存储引擎
(2)用Not Exists 代替Not In
(3)对操作符的优化 尽量不采用不利用索引的操作符
(4)mysql分库分表:
https://jingyan.baidu.com/article/03b2f78c2ec6035ea337ae7f.html
IO流了解吗?它们的区别是什么?
Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。
区别:
(1) 字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
(2)字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
Spring boot 自带的定时任务与Quartz定时任务的区别
spring3.0以后自带的scheduletask任务调度,可以实现quartz的大部分功能,不需要额外引用jar,也不需要另外配置。而且支持注解和配置文件两种。
Quartz 定时任务,这是一个功能很强大的开源的专门用于定时任务调度的框架,也很好的和springboot整合,缺点:配置复杂,需要花费一定的时间去了解和研究
正则表达式以及常用String类方法
常用的正则表达式:https://blog.csdn.net/ZYC88888/article/details/98479629
string类方法:
(1)获取字符串的长度 方法:public int length()
(2)返回字符串中指定位置的字符;public char charAt(int index)
(3)查找字符串在字符串中的位置 方法:public int indexOf(String str)
(4)截取字符串的方法:public String substring(int beginIndex, int endIndex)
(5)字符串比较方法:
该方法是对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。
public int compareTo(String anotherString)
(6)对字符串中的字符进行大小写转换方法:
转换成大写
public String toUpperCase()
转换成小写
public String toLowerCase()
https://jingyan.baidu.com/article/3ea5148995320b52e71bba40.html
多线程同步机制
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁);
如果这个时候同步对象的锁被其他线程拿走了,他(这个线程)就只能等了(线程阻塞在锁池 等待队列中)。
取到锁后,他就开始执行同步代码(被synchronized修饰的代码);线程执行完同步代码后马上就把锁还给同步对象,其他在锁池中 等待的某个线程就可以拿到锁执行同步代码了。
这样就保证了同步代码在统一时刻只有一个线程在执行。
众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题。
关于线程的同步,一般有以下解决方法:
(1)在需要同步的方法的方法签名中加入synchronized关键字。
(2) 使用synchronized块对需要进行同步的代码段进行同步。
(3)使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。
https://blog.csdn.net/hanghangaidoudou/article/details/81606223
IO流中的设计模式
IO流涉及的装饰者设计模式:
FileInputStream inputStream=new FileInputStream(file); //把inputStream装饰成BufferedReader来成为具备缓冲能力的reader BufferedReader reader=new BufferedReader(inputStreamReader);
IO流涉及的适配器设计模式:
FileInputStream fileInput=new FileInputStream(file); //把fileInput文件字节流,通过适配器(InputStreamReader转换流)变为字符流 InputStreamReader input=new InputStreamReader(fileInput);
装饰者模式:
给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例(各种字符流键装饰,各种字节流间装饰)。
适配器模式:
有时候我们需要实现一个接口,但那个接口可能有很多抽象方法,我们只需要其中一个或多个方法。这时候我们可以创建一个类(适配器)实现接口,并重写接口中所有方法(空方法,有方法体,但方法体中无内容)。
当我们需要接口中的某个方法时,只需继承类似于适配器的类 ,然后重写对应的方法即可。 将某个类的接口转换成我们期望的另一个接口表示,目的是消除由于接口不匹配所造成类的不兼容问题(字符流与字节流间互相适配)。
jbos与tomcat区别与优缺点
1. Tomcat是Apache鼎力支持的Java Web应用服务器(注:servlet容器),
由于它优秀的稳定性以及丰富的文档资料,广泛的使用人群,从而在开源领域受到最广泛的青睐。
2. Jboss作为Java EE应用服务器,它不但是Servlet容器,而且是EJB容器
,从而受到企业级开发人员的欢迎,从而弥补了Tomcat只是一个Servlet容器的缺憾。
谢谢观看!博主会不定时的更新题目,如果有侵权可以私聊我qq微信同号:2693394420