Java&Spring过时的经典语录

简介: Java&Spring过时的经典语录

字符串拼接:请用StringBuffer代替String直接相加提高性能

 


过去的理论

 

有没有人告诉过你开发中不要

String newString = "牛郎"+"织女";


而是要根据是否线程安全采用


String newString = new StringBuffer("牛郎").append("织女").toString();


或者


String newString = new StringBuilder("牛郎").append("织女").toString();

 

因为使用过程中会创建多个字符串对象,而String内部是一个固定长度的字符串数组,所以采用这种方法会浪费内存。

 

更新的理论

 

在jdk8之前,+拼接底层使用的是concat做字符串拼接就是说:


String newString = "牛郎"+"织女";


等价于


String newString = "牛郎".concat("织女");

 

String#concat底层将要拼接的字符串以数组的形式复制到一个新数组中,空间开销确实大。但是jdk8对+的拼接底层做了优化:


编译期会把所有的可以final的字符串合成一个字符串。原理就和一般人会用


final long dayInMillisecond = 24*3600*1000;


来代替直接将后面的值计算出来,因为这样更直观,执行期效率是一样的。

 

而对于需要动态拼接的,会内部转成StringBuilder处理。所以对于动态字符串一般来说效果是一样的,对于静态效率反而高些。

 

但是凡事都有特例,也有jdk处理不够智能的地方。但是根据java的走势来说,符合:简单即正义。长远来说,越简单的写法越是jdk优化的重点,效率还会有提升的空间。

 

其他的用法

 

除了一般的字符串拼接,有时候还需要将列表等一些集合用符号(比如,)连接起来,java8以上提供了StringJoiner来完成这件事。比如list拼接:


Lists.newArrayList("迢迢牵牛星",

"皎皎河汉女")


.stream().collect(Collectors.joining(","));


底层用的就是StringJoiner。

 

如果使用google的guava的话,这种情况还有更简单的写法:


Joiner.on(",").join(Lists.newArrayList("迢迢牵牛星","皎皎河汉女"));


它底层用的是StringBuilder和StringJoiner底层是一样的。

 

面试简述SpringMVC的工作原理

 


过去的理论

 

记得2015年前面试必备的一道题,面试者需要像小时候背《咏鹅》一样倒背如流:SpringMVC的工作原理。经典回答是这样:


1112728-20200402232653507-724321908.png


SpringMVC 框架是以请求为驱动,围绕 Servlet 设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。

 

更新的理论

 

早在Spring3里就封装好了RESTful风格开发方式,开发者只需要将请求的Controller替换成RestController或者方法上加上@ResponseBody即可。

 

目前在前后端分离的场景下,经典的SpringMVC中请求流程基本不全用上。

 

Spring提供了两种方法将资源的Java表述形式转换为发送给客户端的表述形式:内容协商和消息转换器。

 

内容协商就是经典的方法,当控制器的处理方法完成时,返回一个逻辑视图。内容协商是一个特殊的视图解释器。

 

消息转换提供了一种更为直接的方式,DispatcherServlet不再需要那么麻烦地将模型数据传送到视图中。只是控制器产生数据给消息转换器后就直接返回给客户端了。

 

使用HttpClient还是OkHttp来做http请求


过去的理论

 

有没有人告诉过你使用OkHttp来代替HttpClient更简洁高效。OkHttp使用build模式创建对象,而且在发送异步请求的时候不需要引入其他的依赖。

 

更新的理论

 

在基于Spring的JAVA服务端开发中一般会使用各种框架帮我们去完成各种单调重复的工作,比如不管是HttpClient还是OkHttp都需要将返回的reponse自己用编解码工作转成对象再处理。但是如果使用feign则可以省去。


<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-core</artifactId>
    <version>8.18.0</version>
</dependency>
<dependency>
    <groupId>com.netflix.feign</groupId>
    <artifactId>feign-jackson</artifactId>
    <version>8.18.0</version>
</dependency>
<dependency>
    <groupId>com.netflix.feign</groupId>
    <!--这里也可以换成feign-httpclient-->
    <artifactId>feign-okhttp</artifactId>
    <version>8.18.0</version>
</dependency>


我们需要创建一个bean来指定url和处理超时重试、


日志打印等高可用方面的问题。


@Bean
public TestHttpService testHttpService() {
    TestHttpService service = Feign.builder()
            .encoder(new JacksonEncoder())
            .decoder(new JacksonDecoder())
            .options(new Request.Options(1000, 3500))
            .retryer(new Retryer.Default(5000, 5000, 3))
            .logger(logger)
            .logLevel(Logger.Level.FULL)
            .target(TestHttpService.class, testUrl);
    return service;
}


Spring的简化开发主要是使用了声明式代替命令式,


在http请求这里当然也可以这么用:


public interface TestHttpService {
    @RequestLine("GET /xxxx?appkey={appkey}&ips={ip}&username={username}&operator={operator}")
    Response getTest(@Param(value = "appkey") String appkey,
                                       @Param(value = "ip") String ip,
                                       @Param(value = "username") String username,
                                       @Param(value = "operator") String operator);
}


运行一下,发现执行过程这么清晰:


[TestHttpService] ---> GET http://xxx/x?appkey=x&ips=x&username=x&operator=x HTTP/1.1
[TestHttpService] ---> END HTTP (0-byte body)
[TestHttpService] <--- HTTP/1.1 200 OK (154ms)
[TestHttpService] connection: keep-alive
[TestHttpService] content-length: 28
[TestHttpService] content-type: application/json;charset=utf-8
[TestHttpService] date: Sun, 29 Mar 2020 02:19:43 GMT
[TestHttpService] m-traceid: -264385071732215405
[TestHttpService] server: openresty
[TestHttpService] version: oceanus
[TestHttpService] 
[TestHttpService] {"data":[],"isSuccess":true}
[TestHttpService] <--- END HTTP (28-byte body)


其他的用法

 

早在Spring3里就已经使用了模板方法来简化http请求的开发,使用RestTemplate不仅可以使用java8的lambda表达式,还可使用消息转换器直接将返回值转成对象的形式,更友好的实现了面向对象编程。当然feign更简洁,并且提供了高可用的支持。

相关文章
|
23天前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
152 3
|
23天前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
676 58
|
11天前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
64 8
|
27天前
|
监控 Java 数据库
从零学 Dropwizard:手把手搭轻量 Java 微服务,告别 Spring 臃肿
Dropwizard 整合 Jetty、Jersey 等成熟组件,开箱即用,无需复杂配置。轻量高效,启动快,资源占用少,内置监控、健康检查与安全防护,搭配 Docker 部署便捷,是构建生产级 Java 微服务的极简利器。
131 2
|
2月前
|
前端开发 Java 开发者
Java新手指南:在Spring MVC中使用查询字符串与参数
通过结合实际的需求和业务逻辑,开发者可以灵活地利用这些机制,为用户提供更丰富而高效的Web应用体验。
99 15
|
3月前
|
JSON 前端开发 Java
Java新手指南:如何在Spring MVC中处理请求参数
处理Spring MVC中的请求参数是通过控制器方法中的注解来完成的。这些注解包括 `@RequestParam`, `@PathVariable`, `@ModelAttribute`, `@RequestBody`, `@RequestHeader`, `@Valid`, 和 `@RequestMapping`。使用这些注解可以轻松从HTTP请求中提取所需信息,例如URL参数、表单数据或者JSON请求体,并将其转换成Java对象以供进一步处理。
299 17
|
3月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
427 0
|
2月前
|
Cloud Native Java API
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
383 0