考试形式:11道主观题,其中10道基础问答选8个回答,关于华为云的问题20分
P.S.提供的答案是我的回答,仅供参考,如果有问题欢迎指正。
1.主观题 (10分)
企业级开发为什么大多使用框架技术?
列出5种以上框架技术。
框架技术:
(1)Spring (2)Flask (3)Django (4)struts2(5)Hibernate (6)MyBatis (7)Hadoop
使用框架技术的最重要意义就是不要重复造轮子。从程序员角度看,使用框架最显著的好处是重用, 由于框架能重用代码,因此从一已有构件库中建立应用变得非常容易,因为构件都采用框架统一定义接口,从而使构件间的通信简单。框架能重用设计。它提供可重用的抽象算法及高层设计,并能将 大系统分解成更小的构件,而且能描述构件间的内部接口。这些标准接口使在已有的构件基础上通过组装建立各种各样的系统成为可能。只要符合接口定义,新的构件就能插入框架中,构件设计者就能 重用构架的设计。框架还能重用分析。所有的人员若按照框架的思想来分析事物,那么就能将它划分为同样的构件,采用相似的解决方法,从而使采用同一框架的分析人员之间能进行沟通。
使用框架技术的另一大意义是降低开发难度。软件系统发展到今天已经很复杂了,特别是服务器端软 件,涉及到的知识,内容,非常广泛。这样开发出完善健壮的软件,对程序员的要求将会非常高。如 果采用成熟,稳健的框架,那么一些基础的通用工作,比如,事物处理,安全性,数据流控制等都可 以交给框架处理,那么程序员只需要集中精力完成系统的业务逻辑设计,可以降低开发难度。
常见的框架往往经历了历史的考验。一种技术,最终都是为业务发展而服务的。从业务的角度来讲。 首先,框架的是为了企业的业务发展和战略规划而服务的,他服从于企业的愿景(vision);其次, 框架最重要的目标是提高企业的竞争能力,包括降低成本、提高质量、改善客户满意程度,控制进度 等方面。最后,框架实现这一目标的方式是进行有效的知识积累。软件开发是一种知识活动,因此知 识的聚集和积累是至关重要的。框架能够采用一种结构化的方式对某个特定的业务领域进行描述,也 就是将这个领域相关的技术以代码、文档、模型等方式固化下来。
2.主观题 (10分)
谈谈SpringBoot项目于Spring、SpringMVC项目的不同点。
我的答案
宏观考量:
Spring 是一个“引擎”;
Spring MVC 是基于Spring的一个 MVC 框架;
Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。
三者联系:
spring在刚开始的时候使用工厂模式(DI)和代理模式(AOP)解耦应用组件
进而开发出适用于Web开发的SpringMVC
在实际开发过程当中会使用到很多样板代码,就开发出了懒人版的SpringBoot。
使用spring开发的步骤:
(1)准备jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java 等等相关jar ...
(2)配置web.xml文件,Listener配置, Filter配置,servlet配置,log4j配置, error配置...
(3)配置数据库链接,配置spring事务
(4)配置视图解析器
(5)开启注解,自动扫描功能
(6)配置完成后, 部署tomcat,启动调试
使用springboot开发步骤:
(1)起步依赖
(2)配置数据源
(3)创建入口 application
区别总结:
Spring包含了SpringMVC,而SpringBoot又包含了Spring或者说是在Spring的基础上做得一个扩展。Spring Boot 对比Spring的一些优点包括:提供嵌入式容器支持、使用命令java -jar独立运行jar、在外部容器中部署时,可以选择排除依赖关系以避免潜在的jar冲突、部署时灵活指定配置文件的选项、用于集成测试的随机端口生成。
从更加细节的层面切入来讲:
Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的ioc和 aop,ioc 提供了依赖注入的容器, aop解决了面向横切面的编程,然后在此两者的基础上实现了其他延伸产品的高级功能。
Spring MVC提供了一种轻度耦合的方式来开发web应用。它是Spring的一个模块,是一个web框架。通过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。
Spring Boot实现了自动配置,降低了项目搭建的复杂度。它主要是为了解决使用Spring框架需要进行大量的配置太麻烦的问题,所以它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。同时它集成了大量常用的第三方库配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用(out-of-the-box)。
3.主观题 (10分)
结合项目谈谈Maven管理项目的技术特点。
我们在开发项目的过程中,会使用一些开源框架、第三方的工具等等,这些都是以jar包的方式被项目所引用,并且有些jar包还会依赖其他的jar包,我们同样需要添加到项目中,所有这些相关的jar包都会作为项目的依赖。通常,一个Java EE项目所依赖的jar包会有很多。然而,这还并非是主要问题,在管理这些jar包过程中,jar包的版本往往是最令人头疼的问题。选择一个jar包的版本,需要考虑它所依赖的jar包是否支持这个版本,并且还需要确认依赖它的jar包能不能对这个版本兼容。所以,在过去的构建项目过程中,整理出这么一堆能让项目正常运行的jar包之后,这个lib目录就会变为禁区。jar包版本更新了,我们也很少会自找麻烦去触碰它。至于是不是存在冗余的jar包,作为开发者很难去一一查证,通常是只要保证能正常运行即可。
在有maven之前我们做项目,都是用eclipse新建一个工程,然后导入相应的Jar包到lib目录下,对外提供的服务,需要使用jar -cvfm ***来进行打包,自己建包写单元测试,整个项目引用开源的Jar包,外部的服务,都要手工去添加jar包,最后管理上很混乱,另外新建的工程只能按照eclipse给出的目录结构,突出的特点就是不够灵活。
但是Maven的出现,解决了开发过程中的这一难题。它可以对项目依赖的jar包进行管理,可以让你的项目保持基本的依赖,排除冗余jar包,并且可以让你非常轻松的对依赖的jar包进行版本升级。而这些仅仅是Maven最基本的功能,它可以在这基础上对项目进行清理、编译、测试、打包、发布等等构建项目的工作。
当我们需要外部的jar包,只需要在pom.xml里面加个<dependency>依赖就可以了,使用maven eclipse的时候eclipse就会自动去关联相应的jar包,按照它们的依赖关系,将整个工程转化为eclipse标准工程,除此之外,还可以自定义archetype原型,即自定义工程的目录结构,不过maven有自带的archetype,对于较大的项目可能要采用分用式需要多个工程配合完成一个项目,那么这个时候就可以新建一个archetype,然后用maven命令生成自己定制化的项目结构。
总体来说,maven对于开发者而言是一个极其有用的工具,可以帮助程序员提高应用开发的效率。
4.主观题 (10分)
结合项目谈谈MVC架构的设计实现,及其与代码、包的对应关系。
mvc架构将一个应用分成3个基本部分:Model(模型)、View(视图)和Controller(控制器),这三部分以最低的耦合进行协同工作,从而提高应用的可扩展性及可维护性。
更通俗地讲M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。
V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。
M即model模型是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。
我们课程中所学的Spring的MVC框架则是对基本的MVC架构进行了扩展,其主要由DispatchServlet、处理器映射、控制器、视图解析器、视图组成。
整体架构的实现是由浏览器客户端发送HTTP请求,交给DispatchServlet来进行统一处理,DispatchServlet需要我们先在应用的.xml文件中进行配置,在将请求分发给Controller之前,会先需要借助HandlerMapping来定位到具体的Controller实现,HandlerMapping接口负责完成客户请求到Controller映射。而Controller接口将处理用户请求,并返回ModelAndView对象给DispatchServlet前端控制器,ModelAndView中就包含了模型(Model)和视图(View)。ViewResolver接口在web应用中负责查找View对象,从而将相应的结果渲染给客户。
具体代码相关内容:首先我们在.xml文件中定义我们项目需要的Java配置,接着需要定义POJO实体类来定义我们要操作对象的属性,定义Controller层来包含用户请求的处理逻辑,并使用RequestMapping来将请求和处理方法一一对应,最后在service层中使用@autowired进行依赖注入。
5.主观题 (10分)
请结合实例,写出实现页面信息国际化的技术路线?
举出关键代码
-
编写国际化资源属性文件
1)我们需要在i18n/admin文件夹下创建adminMessage.properties、adminMessage_en_US.properties和adminMessage_zh_CN.properties资源属性文件分别表示默认加载的信息、英文信息、中文信息
2)在i18n/before中编写用户模块的国际化信息
3)在i18n/common中编写公共模块的国际化信息
- 添加配置文件,引入资源属性文件(application.properties文件中)spring.messages.basename=i18n/admin/adminMessages,i18n/before/beforeMessages,i18n/common/commonMessages
- 重写localeResolver方法配置语言区域选择
用配置类LocaleConfig配置类来实现WebMvcConfigurer接口,并注册拦截器(关键代码见下)
/**
* 注册拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
- 在controller包中创建控制器类(通过@RequestMapping将请求和处理方法一一对应)
- 创建视图页面,并获得国际化信息
在templates目录下的i18n文件夹下创建admin.html、before.html、first.html ,在其中使用th:text="#{xxx}"获取国际化信息(代码见下)
<body><span th:text="#{admin}"></span><br><a th:href="@{/i18n/first}" th:text="#{return}"></a>
</body>
6.主观题 (10分)
请写出Thymeleaf中的5个重要标签;
结合实例,给出其应用实例。
1.th:each
集合对象遍历,功能类似JSTL标签<c:forEach>。示例代码如下:
<div class="col-md-4 col-sm-6" th:each="gtype:${gtypes}">
<div>
<p th:text="${gtype.id}"></p>
<p th:text="${gtype.typename}"></p>
</div>
</div>
2.th:href
定义超链接,类似<a>标签的href属性。value形式为@{/logout},示例代码如下:
<a th:href="@{/gogo}"></a>
3.th:id
div的id声明,类似html标签中的id属性
<div th:id ="stu+(${rowStat.index}+1)"></div>
4.th:fragment
声明定义该属性的div为模板片段,常用于头文件、页尾文件的引入。常与th:include、th:replace一起使用。
ch5_1的src/main/resources/templates目录下声明模板片段文件footer.html
<!-- 声明片段content -->
<div th:fragment="content" >
主体内容
</div>
<!-- 声明片段copy -->
<div th:fragment="copy" >
</div>
5.th:object:用于表单数据绑定,将表单绑定到后台的controller的一个javaBean参数,用于表单数据绑定
7.主观题 (10分)
结合实例,写出Spring Data JPA中使用排序和分页查询的实现。
Spring Data JPA通过为我们提供Sort类,Page接口以及Pageable接口来实现排序和分页查询
- 首先,我们需要创建持久化实体类
- 创建数据访问层,参照数据访问接口,在函数参数中传入Sort类对象
例子:
public interface AuthorRepository extends JpaRepository<Author, Integer>{
List<Author> findByAnameContaining(String aname, Sort sort);
}
- 创建业务层,使用sortColumn来实现排序列
aname参数实现模糊查询,sortColumn来实现排序列:
List<Author> findByAnameContaining(String aname, String sortColum){
//按sortColum降序排序
return authorRepository.findByAnameContaining(aname, new Sort(Direction.DESC, sortColum));
}
- 分页查询示例:
public String findAllAuthorByPage(Integer page, Model model){
if(page == null) {//第一次访问findAllAuthorByPage方法时
page = 1;
}
int size = 2;//每页显示2条
//分页查询,of方法的第一个参数代表第几页(比实际小1),第二个参数代表页面大小,第三个参数代表排序规则
Page<Author> pageData = authorRepository.findAll(PageRequest.of(page-1, size, new Sort(Direction.DESC, "id")));
//获得当前页面数据并转换成List<Author>,转发到视图页面显示
List<Author> allAuthor = pageData.getContent();
model.addAttribute("allAuthor",allAuthor);
//共多少条记录
model.addAttribute("totalCount", pageData.getTotalElements());
//共多少页
model.addAttribute("totalPage", pageData.getTotalPages());
//当前页model.addAttribute("page", page);
return "index";
}
5.创建控制器,使用@RequestMapping注解来实现请求和处理的一一对应
6.创建view视图页面
8.主观题:
结合实例,出些SpringBoot实现REST风格的表达特点及所需的技术支持关键点。
表达特点:
资源:网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。资源总要通过某种载体反应其内容,文本可以用txt格式表现,也可以用HTML格式、XML格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现;JSON是现在最常用的资源表示格式。
统一接口:数据的元操作,即CRUD(create, read, update和delete,即数据的增删查改)操作,分别对应于HTTP方法:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,这样就统一了数据操作的接口,仅通过HTTP方法,就可以完成对数据的所有增删查改工作。
URI:可以用一个URI(Universal Resource Identifier,统一资源定位符)指向资源,即每个URI都对应一个特定的资源。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或识别符。一般的,每个资源至少有一个URI与之对应,最典型的URI即URL。
URL 的格式由下列三部分组成 :
第一部分是协议 ( 或称为服务方式 );
第二部分是存有该资源的主机 IP 地址 ( 有时也包括端口号 );
第三部分是主机资源的具体地址。
URI 一般由三部分组成 :
访问资源的命名机制。
存放资源的主机名。
资源自身的名称,由路径表示
无状态:所有的资源,都可以通过URI定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。
技术支持关键点:
由于RESTful风格的服务是无状态的,认证机制尤为重要。
认证机制解决的问题是,确定访问资源的用户是谁;认证机制基本上是通用的,本真REST + OAuth是RESTful 是微服务的标配。
权限机制解决的问题是,确定用户是否被许可使用、修改、删除或创建资源。权限机制通常与服务的业务逻辑绑定,因此权限机制需要在每个系统内部定制。
9.主观题 (10分)
结合实例,写出Spring Boot 安全控制实现的关键技术。
- 授权(Authorization)即确定用户在当前应用系统下所拥有的功能权限
- 认证(Authentication)确认用户访问当前系统的身份
核心验证器 AuthenticationManager
该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数;
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
ProviderManager:
它是 AuthenticationManager 的一个实现类,提供了基本的认证逻辑和方法;它包含了一个 List<AuthenticationProvider> 对象,通过 AuthenticationProvider 接口来扩展出不同的认证提供者(当Spring Security默认提供的实现类不能满足需求的时候可以扩展AuthenticationProvider 覆盖supports(Class<?> authentication)方法);
- ProviderManager代码实现中具体思想:
遍历所有的 Providers,然后依次执行该 Provider 的验证方法
如果某一个 Provider 验证成功,则跳出循环不再执行后续的验证;
如果验证成功,会将返回的 result 既 Authentication 对象进一步封装为 Authentication Token;
比如 UsernamePasswordAuthenticationToken、RememberMeAuthenticationToken 等;这些 Authentication Token 也都继承自 Authentication 对象;
如果 #1 没有任何一个 Provider 验证成功,则试图使用其 parent Authentication Manager 进行验证;
是否需要擦除密码等敏感信息;
- 验证逻辑:
AuthenticationManager 接收 Authentication 对象作为参数,并通过 authenticate(Authentication) 方法对其进行验证;AuthenticationProvider实现类用来支撑对 Authentication 对象的验证动作;UsernamePasswordAuthenticationToken实现了 Authentication主要是将用户输入的用户名和密码进行封装,并供给 AuthenticationManager 进行验证;验证完成以后将返回一个认证成功的 Authentication 对象;
- 总结:
UserDetailsService接口作为桥梁,是DaoAuthenticationProvier与特定用户信息来源进行解耦的地方,UserDetailsService由UserDetails和UserDetailsManager所构成;UserDetails和UserDetailsManager各司其责,一个是对基本用户信息进行封装,一个是对基本用户信息进行管理;
特别注意,UserDetailsService、UserDetails以及UserDetailsManager都是可被用户自定义的扩展点,我们可以继承这些接口提供自己的读取用户来源和管理用户的方法,比如我们可以自己实现一个 与特定 ORM 框架,比如 Mybatis 或者 Hibernate,相关的UserDetailsService和UserDetailsManager;
10.结合华为云实践项目,回答以下问题:
(1)项目所设计的所有华为产品
(2)云服务技术、负载均衡、弹性伸缩技术的特点
(3)存、算分离的实现,为什么数据库不用公网IP?
(1)GaussDB(for MySQL)、弹性云服务器Elastic Cloud Server(ECS)
(2)云服务技术特点:
1.大规模、分布式
“云”一般具有相当的规模,一些知名的云供应商如Google云计算、Amazon、IBM、微软、阿里等也都拥能拥有上百万级的服务器规模。而依靠这些分布式的服务器所构建起来的“云”能够为使用者提供前所未有的计算能力。
2.虚拟化
云计算都会采用虚拟化技术,用户并不需要关注具体的硬件实体,只需要选择一家云服务提供商,注册一个账号,登陆到它们的云控制台,去购买和配置你需要的服务(比如 云服务器,云存储,CDN等等),再为你的应用做一些简单的配置之后,你就可以让你的应用对外服务了,这比传统的在企业的数据中心去部署一套应用要简单方便得多。而且你可以随时随地通过你的PC或移动设备来控制你的资源,这就好像是云服务商为每一个用户都提供了一个IDC(Internet Data Center)一样。
3.高可用性和扩展性
那些知名的云计算供应商一般都会采用数据多副本容错、计算节点同构可互换等措施来保障服务的高可靠性。基于云服务的应用可以持续对外提供服务(7*24小时),另外“云”的规模可以动态伸缩,来满足应用和用户规模增长的需要。
4.按需服务
用户可以根据自己的需要来购买服务,甚至可以按使用量来进行精确计费。这能大大节省IT成本,而资源的整体利用率也将得到明显的改善。
5.安全
网络安全已经成为所有企业或个人创业者必须面对的问题,企业的IT团队或个人很难应对那些来自网络的恶意攻击,而使用云服务则可以借助更专业的安全团队来有效降低安全风险。
负载均衡的特点:当应用访问一个具有多个实例的微服务时,会涉及到路由负载均衡。CSE提供基于Ribbon的负载均衡方案,可以通过配置文件配置负载均衡策略,支持随机,轮询、会话保持和基于响应时间的权值等多种负载均衡路由策略。
弹性伸缩技术的特点:
可根据用户的业务需求,通过策略自动调整其业务的资源。具有自动调整资源、节约成本开支、提高可用性和容错能力的优势。适用不同场景:
1.访问流量较大的论坛网站,业务负载变化难以预测,需要根据实时监控到的云服务器CPU使用率、内存使用率等指标对云服务器数量进行动态调整。
2.电商网站,在进行大型促销活动时,需要定时增加云服务器数量和带宽大小,以保证促销活动顺利进行。
3.游戏公司:每天中午12点及晚上6点至9点间需求增长,需要定时扩容。
(3) 存、算分离的实现:GaussDB(for MySQL)采用计算与存储解耦的技术架构,让所有的节点都共享一个存储,也就是说,增加计算节点时,无需调整存储资源,真正做到计算与存储分离,并且可支持 15 个只读节点的扩展,主节点和只读节点之间是 Active-Active 的 Failover 方式,计算节点资源得到充分利用,由于使用共享存储,降低了用户使用成本。完美契合了企业级数据库系统对高可用性、性能和扩展性、云服务托管的需求。GaussDB(for MySQL)将MySQL存储层变为独立的存储节点,在GaussDB(for MySQL)中认为日志即数据,将日志彻底从MySQL计算节点中抽离出来,都由存储节点进行保存,与传统 RDS for MySQL 相比,不再需要刷 page,所有更新操作都记录日志,不再需要 double write,从而大大减少了网络通信。
为什么数据库不用公网IP:
数据库的IP大多是内网IP。内网IP地址就是私有IP地址,不允许在公网上面传递,只能供内部使用。所以较为安全。在Mysql数据库中执行以下语句放开root用户的外网访问权限