可以在 @RequestMapping 注解里面加上 method=RequestMethod.GET 或者使用 @GetMapping 注解
JRE 代表 Java 运行时(Java run-time),是运行 Java 应用所必须的。JDK 代表 Java 开发工具(Java development kit),是 Java 程序的开发工具,如 Java 编译器,它也包含 JRE。JVM 代表 Java 虚拟机(Java virtual machine),它的责任是运行 Java 应用。JIT 代表即时编译(Just In Time compilation),当代码执行的次数超过一定的阈值时,会将 Java 字节码转换为本地代码,如,主要的热点代码会被准换为本地代码,这样有利大幅度提高 Java 应用的性能。
mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp
maven 有三套生命周期,分别为:
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。 所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。简而言之,第一范式就是无重复的列。
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键、主码。 第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性,消除冗余
web.xml 文件是用来初始化 web 应用的配置信息:比如 Welcome 页面、 servlet 、 servlet-mapping 、 filter 、listener、启动加载级别等。当你的 web 工程没用到这些时,你可以不用 web.xml 文件来配置你的 Application。
简单说一下,web.xml 的加载过程。当我们启动一个 WEB 项目容器时,容器包括( JBoss,Tomcat 等)。首先会去读取 web.xml 配置文件里的配置,当这一步骤没有出错并且完成之后,项目才能正常的被启动起来。
启动 WEB 项目的时候,容器首先会去读取 web.xml 配置文件中的两个节点: 和
紧接着,容器创建一个 ServletContext(application) ,这个 web 项目的所有部分都将共享这个上下文。容器以的 name 作为键,value 作为值,将其转化为键值对,存入 ServletContext。
容器创建中的类实例,根据配置的 class 类路径来创建监听,在监听中会有初始化方法,启动Web应用时,系统调用 Listener 的该方法 contextInitialized(ServletContextEvent args),在这个方法中获得:
ServletContext application =ServletContextEvent.getServletContext();
context-param的值= application.getInitParameter("context-param的键");
得到这个 context-param 的值之后,你就可以做一些操作了。举例:你可能想在项目启动之前就打开数据库,那么这里就可以在中设置数据库的连接方式(驱动、url、user、password),在监听类中初始化数据库的连接。这个监听是自己写的一个类,除了初始化方法,它还有销毁方法,用于关闭应用前释放资源。比如:说数据库连接的关闭,此时,调用 contextDestroyed(ServletContextEvent args),关闭Web应用时,系统调用 Listener 的该方法。
接着,容器会读取,根据指定的类路径来实例化过滤器。
以上都是在WEB项目还没有完全启动起来的时候就已经完成了的工作。如果系统中有 Servlet ,则 Servlet 是在第一次发起请求的时候被实例化的,而且一般不会被容器销毁,它可以服务于多个用户的请求。所以,Servlet的初始化都要比上面提到的那几个要迟。总的来说,web.xml 的加载顺序是: -> -> -> 。其中,如果web.xml中出现了相同的元素,则按照在配置文件中出现的先后顺序来加载。
1)解决 post 请求乱码问题:
在 web.xml 中加入:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.Springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)get 请求中文参数出现乱码解决方法有两个:
①修改 tomcat 配置文件添加编码与工程编码一致,如下:
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
②另外一种方法对参数进行重新编码:
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。
主观题
默认情况下, context:component-scan 查找使用构造型(stereotype)注解所标注的类,如@Component(组件),@Service(服务),@Controller(控制器),@Repository(数据仓库),在xml配置了这个标签后,Spring 可以自动去扫描 base-pack 下面或者子包下面的 java 文件,如果扫描到有 @Component 、@Controller 、@Service等这些注解的类,则把这些类注册为 bean
@Autowired 与 @Resource 都可以用来装配 bean . 都可以写在字段上,或写在 setter 方法上。
@Autowired 默认按类型装配(这个注解是属于 Spring 的),默认情况下必须要求依赖对象必须存在,如果要允许 null 值,可以设置它的 required 属性为 false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合 @Qualifier 注解进行使用,如下:
@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;
@Resource(这个注解属于 J2EE 的),默认安装名称进行装配,名称可以通过 name 属性进行指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在 setter 方法上默认取属性名进行装配。当找不到与名称匹配的 bean 时才按照类型进行装配。但是需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配。
@Resource(name="baseDao")
private BaseDao baseDao;
404错误:
500错误:
网站后台管理系统主要是用于对网站前台的信息管理,如文字、图片、影音、和其他日常使用文件的发布、更新、删除等操作,同时也包括会员信息、订单信息、访客信息的统计和管理。简单来说就是对网站数据库和文件的快速操作和管理系统,以使得前台内容能够得到及时更新和调整。
主观题
Bootstrap 是美国 Twitter 公司的设计师 Mark Otto 和 Jacob Thornton 合作基于 HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷。
Bootstrap 提供了优雅的 HTML 和 CSS 规范,由动态 CSS 语言 Less 编写写成。Bootstrap 一经推出后颇受欢迎,一直是 GitHub 上的热门开源项目(截止十三整理这篇文章,Star 数目为125763),包括 NASA 旗下的 MSNBC Breaking News 都使用了该项目。是国内一些移动开发者较为熟悉的框架,如 WeX5 等前端开源框架,也是基于 Bootstrap 源码进行性能优化升级而来。
选型,首先要明确目的,之后根据自己的需求和技术能力进行选择,确定自己需要开发什么样的产品或者说公司更需要哪种技术栈的人才,然后针对性的去学习,这样才会事半功倍,复用性和可维护性是十分重要的指标,工具性的产品就是为了减少代码臃肿和提升开发效率,在技术选型中这两个指标一定不能忽略,之后则需要从工具的成熟度、社区活跃度、学习成本来考虑。
登录的本质就是身份验证和登录状态的保持。
进入登录页-->输入账号密码-->参数验证-->发送登陆请求-->查询数据库并进行身份验证
主观题
分页功能在网页中是非常常见的一个功能,其作用也就是将数据分割成多个页面来进行显示。
分页功能的使用可以提升系统性能,也比较符合用户习惯,符合页面设计规范
分页的实现分为真分页和假分页两种,也就是物理分页和逻辑分页。
实现原理:SELECT * FROM xxx [WHERE...] LIMIT #{param1}, #{param2}
第一个参数是开始数据的索引位置
第二个参数是要查询多少条数据
实现原理: 一次性将所有的数据查询出来放在内存之中,每次需要查询的时候就直接从内存之中去取出相应索引区间的数据
MultipartResolver 用于处理文件上传,当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller。
通过 maxUploadSize 参数进行限制,配置如下:
<bean id="multipartResolver" class="org.Springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值为5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
逻辑删除是名义上的删除,而物理删除是真正的删除。
比如,物理删除的实现代码为:
delete from tb_xxx where id = 10
而逻辑删除的实现代码为:
update tb_xxx set is_deleted=1 where id = 10
在实际开发过程中,删除数据一定要慎重,对于重要的数据,最好不要轻易物理删除(即直接删除),在必要的情况下可以使用逻辑删除的方法,即设置一个删除标志的列属性表示逻辑删除,比如本项目中使用的就是 is_deleted
字段来标识记录是否被删除。
与单图上传相比,点击上传按钮后可以在文件框中选择多张图片并完成上传即是多图上传。
使用多图上传的原因:
我们可以把大文件切割成若干个小文件,全部传输到服务器后再进行文件的合并,这样就可以实现大文件的上传了,通常的解决方案就是分片上传。
auto: false,// 选完文件后,是否自动上传
swf: 'plugins/webupload/Uploader.swf',// swf文件路径
server: '/images',// 文件接收服务端url
method: 'POST',// 服务端请求方法
pick: '#fileUploader',// 选择文件的按钮
fileNumLimit: 10,//文件总数量只能选择10个,多于10个部分不会加入上传队列
fileSizeLimit: 100 * 1024 * 1024,//验证文件总大小是否超出限制, 超出则不允许加入队列 100M
fileSingleSizeLimit: 4 * 1024 * 1024,//验证单个文件大小是否超出限制, 超出则不允许加入队列 4M
compress: false,//配置压缩的图片的选项。如果此选项为false, 则图片在上传前不进行压缩。
chunked: true, //开启分块上传
chunkSize: 5 * 1024 * 1024,//分片大小 默认5M
chunkRetry: 3,//网络问题上传失败后重试次数
threads: 4,//上传并发数,允许同时最大上传进程数,默认值为3
accept: {//指定接受哪些类型的文件
title: 'Images',
extensions: 'gif,jpg,jpeg,bmp,png',// 只允许选择部分图片格式文件,可自行修改
mimeTypes: 'image/*'
}
导出 word或者 excel(报表),方便数据查看。 导入 word或者 excel,方便数据录入。 提供了编程方式控制 office 文档,而不仅仅是人为操作。
针对 xls
格式,相应的类有:
针对 xlsx
格式,相应的类有:
读取 Excel,相应的方法有:
//获取文件流
InputStream is = new FileInputStream(file);
//得到Excel工作簿对象
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
//得到Excel工作表对象
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
//得到Excel工作表的指定行对象
XSSFRow xssfRow = xssfSheet.getRow(i);
//得到Excel工作表指定行的单元格
XSSFCell xssfCell = xssfRow.getCell(i);
//得到单元格样式
XSSFCellStyle xssfCellStyle = xssfCell.getCellStyle();
创建 Excel,相应的方法有:
//创建工作薄
XSSFWorkbook wb = new XSSFWorkbook();
//创建工作表对象
XSSFSheet sheet = wb.createSheet("sheet1");
//创建Excel工作表的行对象
XSSFRow row = sheet.createRow(i);
//创建单元格样式
XSSFCellStyle style = wb.createCellStyle();
//创建Excel工作表指定行的单元格
XSSFCell cell = row.createCell(i);
//设置Excel单元格的值
cell.setCellStyle(style);
类型转换问题,需要根据单元格的数据类型进行判断和转换。
case XSSFCell.CELL_TYPE_NUMERIC: // 数字
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(cell.getNumericCellValue());
break;
case XSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case XSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case XSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case XSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
富文本编辑器,是一种可内嵌于浏览器,所见即所得的文本编辑器。
富文本编辑器不同于文本编辑器(以使用 textarea、input 标签为主),也可以叫做图文编辑器。在富文本编辑器里可以编辑类型丰富的内容,如文字、图片、表情、代码……应有尽有,满足你的大部分需求。
当编辑内容越来越复杂,普通的 textarea、input 标签无法满足业务需求时,推荐使用富文本编辑器来解决这些问题,比如新闻详情、商品详情、文章详情等需要图文混排等复杂需求的功能场景。
以上为最需要注意的三点,其他的功能为附加功能,比如:
一个字段即可,存储的内容为字符串,但是该字段的属性最好设置为 TEXT 或者 MEDIUMTEXT
等等
以某度搜索和某东商品搜索为例,某度搜索的搜索维度主要是关键字,也可以选择时间维度,某东商品搜索时主要有商品类别、商品信息、商品价格等维度。从这两个例子中,我们可以看出搜索维度的关键性,只有选择正确的搜索维度,才能更高效的实现搜索功能,搜索条件需要根据自身业务来规划,主要的维度也就是“关键字”、“时间范围”、“数值区间”。
前端:
后端:
LIKE
CONCAT
Linux 服务器间可以通过 scp 命令传输文件。
执行命令 rz
,即可在 Windows 系统内直接下载对应的安装包并通过命令行传输到 Linux 系统内。使用这种方式,首先需要确定 Linux 服务器中是否已安装了 rz
命令,默认是没有安装的。执行命令 yum install -y lrzsz
,即可完成该命令的安装。
该错误提示表示“没有文件或目录”。
首先执行 cd 命令进入 Tomcat 的 bin
目录,之后执行 ./startup.sh
即可启动 Tomcat 服务器,执行 ./shutdown.sh
即可关闭 Tomcat 服务器。
执行 jar -xf xxx.war
即可, xxx.war 为需要解压的war包名。
首先将基础环境搭建完成,如 JDK 、 Tomcat 、 MySQL 等,之后将项目 war 包放入 Tomcat 的 webapp 对应的目录下,最后启动 Tomcat 服务器即可。
System.out.print
更直观、更方便。使用 syso 快捷键瞬间就能编写一条打印语句,很顺手,相信这也是很多 Java 新手对它情有独钟的原因。然而,该语句与 Java 业务程序运行在同一线程中,业务程序需等待它执行完成后才可执行,导致资源被占用。而 Log 工具具有异步、解耦、输出灵活、多种日志策略等特点,诸如 Log4j、Logback 等日志工具打印调试信息,属于异步线程调用,不会使程序处于等待状态。
System.out.print
在控制台输出语句,且只能输出到控制台。功能上线后,开发者不可能一直盯着控制台看日志信息的打印输出,况且日志文件需要保留,以供日后分析使用,存储和清理也需要一套管理规范,这些 System.out.print
都做不到,而 Log 工具可以。
Log4J 中日志记录的优先级分为 OFF、TRACE、DEBUG、INFO、WARN、ERROR、 FATAL、ALL。通常,Log4J 建议只使用其中的四个级别,优先级从低到高分别是 DEBUG、INFO、WARN、ERROR,Log4J 针对不同包指定不同级别。
Log4J 利用 org.apache.log4j.jdbc.JDBCAppender 可以将日志输出到 MySQL 对应的表中。
大部分项目组应该都会要求开发人员编写单元测试,而且也有单元测试覆盖率的指标。
主观题
主观题
通常是业务层方法会做单元测试。
JUnit 是一个Java语言的单元测试框架,使用 Junit 能让我们快速的完成单元测试。通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。
//第一步,注册驱动程序
//com.MySQL.jdbc.Driver
Class.forName("数据库驱动的完整类名");
//第二步,获取一个数据库的连接
Connection conn = DriverManager.getConnection("数据库地址","用户名","密码");
//第三步,创建一个会话
Statement stmt=conn.createStatement();
//第四步,执行SQL语句
stmt.executeUpdate("SQL语句");
//或者查询记录
ResultSet rs = stmt.executeQuery("查询记录的SQL语句");
//第五步,对查询的结果进行处理
while(rs.next()){
//操作
}
//第六步,关闭连接
rs.close();
stmt.close();
conn.close();
受限于数据库的自身配置,数据库连接数量也是有限的。系统中的每一个 Connection 对象均对应一个物理数据库连接,每次与数据库的交互操作都需要打开和关闭一个物理连接,这个过程很大程度上影响着系统性能。数据库连接池使数据库连接对象得到重复利用,从而尽可能地减少程序与数据库交互时所占用的内存等资源消耗,对系统性能的提升有极大帮助。在系统中引入连接池技术可以提高运行效率,同时,某些连接池技术通过功能扩展还可用来监视数据库连接的数量、使用情况等等。
当用户需要进行数据库访问操作时,并非直接建立一个 Connection 对象,而是从连接池中取出一个已建立的空闲连接对象。如果存在空闲连接,则直接将连接分配给客户使用。如果没有空闲连接,则查看当前所开的数据库连接对象的数量是否已达到初始化时设置的最大连接数——如果没达到,则新建一个连接并返回给系统使用;如果已达到,则按设定的最大等待时间等待连接池返回,若超出了最大等待时间,则抛出异常。当释放数据库连接时,首先判断该连接是否有效,连接池内部会根据初始化设置定期检查池中连接对象的可用性,如果不可用则删除该连接对象,以最大程度保证从连接池中得到的 Connection 对象是可用的。连接池的设计策略保证了数据库连接的有效性和连接资源的复用性,降低了频繁与数据库建立物理连接、关闭连接所带来的系统资源开销
主观题,可结合文中的结果进行测试。
相较于其他数据库连接池,Druid 功能最为全面,SQL 拦截等功能,统计数据较为全面,具有良好的扩展性。
主观题,可结合文中的结果进行测试。
关于二者的对比,两位作者也都坐不住了,甚至公开在issue中发表各自的观点,可参考issue,结合各方评测可以得出以下结论。
首先在配置文件中开启 stat 拦截器:
<!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat"/>
之后在 web.xml 中增加 Druid 监控相关设置:
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 不允许清空统计数据 -->
<param-name>resetEnable</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>gitchat-ssm</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>FnzW0m49JjasWH5N</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
其中 resetEnable 设置为 false 代表不允许清空统计数据,这个配置可以根据自身业务进行修改。如果在开发测试期间,设置为 false 可以看到更多的数据。loginUsername 和 loginPassword 是登录监控面板的登录信息,最后通过设置 servlet-mapping
将 Druid 监控的地址暴露出来。
应用服务器资源往往很有限,技术变革相对也较缓慢,而数据库每秒能接受的请求次数也是有限的(文件的读写能力也是有限的),要想利用有限的资源提供尽可能大的吞吐量和系统性能,一个有效的办法就是引入缓存技术。数据查询时,可以先从缓存中直接获取目标数据,由缓存服务分担一部分流量压力,从而减少关系型数据库的直接压力,有效提升响应速度。
1、缓存存储策略
并不是所有数据都需要进行缓存,适合缓存的数据主要有以处几个特征:
2、缓存数据一致性
缓存和数据库是两套存储系统,数据变更时需保证两者之间的数据一致性,否则将会出现这样的事故:MySQL 数据库中的数据已做了修改,但从 Redis 中读取的仍是老数据。为了保证缓存数据的一致性,在进行数据库修改、删除操作时,我们需要对可能影响到的缓存进行更新或者清除。
主观题
软件架构即“有关软件整体结构与组件的抽象描述,用于指导大型软件系统各方面的设计”。
主观题
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。
2、weight(轮询权值)
weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。
3、ip_hash
每个请求按访问 IP 的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器。
4、fair
比 weight、ip_hash 更加智能的负载均衡算法,fair 算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx 本身不支持 fair,如果需要这种调度算法,则必须安装 upstream_fair 模块。
5、url_hash
按访问的URL的哈希结果来分配请求,使每个 URL 定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx 本身不支持 url_hash,如果需要这种调度算法,则必须安装 Nginx 的 hash 软件包。
服务器集群是指将很多服务器集中起来提供同一种服务,在客户端看来好像只有一个服务器。相比于单机部署,集群拥有更多的计算资源,可提升系统的处理能力和响应速度。
不同。
分布式:一个业务分拆成多个子业务,或者本身就是不同的业务,部署在不同的服务器上,即分布式是指多个系统协同合作完成一个特定任务的系统,它的的主要工作是分解任务,将职能拆解。
集群主要的使用场景是为了分担请求的压力,也就是在几个服务器上部署相同的应用程序,来分担客户端请求。
分布式的主要应用场景是单台机器已经无法满足这种性能的要求,必须要融合多个节点,并且节点之间是相关之间有交互的。
负载平衡也称负载共享,是指对系统中的负载情况进行动态调整,以尽量消除或减少系统中各节点负载不均衡的现象。具体实现方法是将过载节点上的任务转移到其他轻载节点上,尽可能实现系统各节点的负载平衡,从而提高系统的吞吐量。负载共享有利于统筹管理分布式系统中的各种资源,便于利用共享信息及其服务机制扩大系统的处理能力。
本文中讲解的 Nginx 只是其中的一种负载均衡器技术--“反向代理负载均衡”,其他的负载均衡方式有:
简单来说,在 B/S 架构中,静态资源一般指 Web 服务器对应目录中的资源文件。客户端发送请求到 Web 服务器后,Web 服务器(比如 Tomcat)直接从文件目录中获取文件并返回给客户端,客户端解析并渲染显示出来,比如 HTML、CSS、JavaScript、图片等文件。这些文件原样返回给客户端,并不会在 Web 服务器端有所改变。而动态资源则与此不同,这些资源是会动态改变的。在复杂的互联网架构中,往往会因为需求不同、场景不同、甚至用户不同而需要 Web 服务器返回不同的数据,这就需要运行 Web 服务器中的程序,通过与数据库交互及其他逻辑运算,返回不同的数据资源,这些数据资源为动态资源。
不一定,需要根据实际业务场景来考虑,如果系统压力不大或者静态资源请求也不是特别多的情况下,并不是一定要做动静分离。
主观题,可参考文中对比结果。