<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[dashengjava的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/dashengjava</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; dashengjava]]></copyright><item><title><![CDATA[深入理解Java虚拟机笔记---判断对象是否存活]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/120180929</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/120180929</guid><author>dashengjava</author><pubDate>Wed, 08 Sep 2021 15:26:05 +0800</pubDate><description><![CDATA[堆中几乎存放着Java世界中所有的对象实例，垃圾收集器在对堆回收之前，第一件事情就是要确定这些对象哪些还“存活”着，哪些对象已经“死去”(即不可能再被任何途径使用的对象)
1.引用计数算法
很多教科书判断对象是否存活的算法是这样的：给对象中添加一个引用计数器，每当有一个地方引用它时，计数器值加1；当引用失效时，计数器减1；任何时刻计数器都为0的对象就是不可能再被使用的。
引用计数算法(Reference Counting)的实现简单，判断效率也很高，在大部分情况下它都是一个不错的算法。但是Java语言中没有]]></description><category></category></item><item><title><![CDATA[生产环境中，如何提升springboot服务吞吐量]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119891186</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119891186</guid><author>dashengjava</author><pubDate>Tue, 24 Aug 2021 17:04:14 +0800</pubDate><description><![CDATA[背景
生产环境偶尔会有一些慢请求导致系统性能下降，吞吐量下降，下面介绍几种优化建议。
方案
1、undertow替换tomcat
电子商务类型网站大多都是短请求，一般响应时间都在100ms，这时可以将web容器从tomcat替换为undertow，下面介绍下步骤：
1、增加pom配置

            org.springframework.boot
            spring-boot-starter-web
            
                
         ]]></description><category></category></item><item><title><![CDATA[哪些代码破坏了LSP?]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119648619</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119648619</guid><author>dashengjava</author><pubDate>Thu, 12 Aug 2021 16:58:14 +0800</pubDate><description><![CDATA[哪些代码破坏了LSP？

实际上，里式替换原则还有另外一个更加能落地、更有指导意义的描述，那就是 Design By Contract，中文翻译就是 按照协议来设计。

子类在设计的时候，要遵守父类的行为约定（或者叫协议）。父类定义了函数的行为约定，那子类可以改变函数的内部实现逻辑，但不能改变函数原有的行为约定。这里的行为约定包括：

函数声明要实现的功能；
对输入、输出、异常的约定；
注释中所罗列的任何特殊说明。

实际上，定义中父类和子类之间的关系，也可以替换成接口和实现类之间的关系。
为了更好地理解这]]></description><category></category></item><item><title><![CDATA[分布式缓存redis，看这一篇就够了]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119348961</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119348961</guid><author>dashengjava</author><pubDate>Tue, 03 Aug 2021 14:13:33 +0800</pubDate><description><![CDATA[redis是什么？

简单来说redis是一个开源的使用ANSI C语言编写的内存数据库，使用key-value的数据结构。支持数据持久化到硬盘，支持多种api语言的连接。通常当做缓存处理。

安装redis

redis官网：https://redis.io 英语好的看官网，下载linux版本redis
redis for windows: https://github.com/MicrosoftArchive/redis/releases ，windows版下载到本地直接安装即可使用。



windo]]></description><category></category></item><item><title><![CDATA[异常这样处理，对用户更友好]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119210294</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119210294</guid><author>dashengjava</author><pubDate>Thu, 29 Jul 2021 14:19:36 +0800</pubDate><description><![CDATA[在项目中，经常有一些业务需要抛出异常，但是如果后台直接抛出throw new Exception的话，前端就很难看，对用户提示也不够友好，今天我们就来解决这个问题。

先建立一个工程，模拟将异常抛出。如下：

@RestController
public class DemoController {

    @GetMapping("test")
    public String test() throws Exception{
        if(true){
            throw n]]></description><category></category></item><item><title><![CDATA[配置文件这样写，多环境自由切换]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119109287</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119109287</guid><author>dashengjava</author><pubDate>Mon, 26 Jul 2021 14:43:53 +0800</pubDate><description><![CDATA[在之前的章节中我们讲过yml配置文件，小伙伴们还记得吗？很好用，但是实际生产中会有很多问题。


测试是一套配置，生产是一套配置；不同人开发不同的模块，共用一个yml文件容易发生冲突；
本地开发需要本地化配置调试，本节咱们就把这些头疼的问题统统解决掉。


首先我们建立一个工程，将application.properties文件后缀改成application.yml。

name: 张三
lesson: springboot
desc: ${name}同学正在努力学习${lesson}!!! #占位符

.]]></description><category></category></item><item><title><![CDATA[十分钟！教你玩转SprintBoot定时任务]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/119026822</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/119026822</guid><author>dashengjava</author><pubDate>Fri, 23 Jul 2021 11:01:55 +0800</pubDate><description><![CDATA[常用的定时任务有两种：

基于注解
基于接口

基于注解@Scheduled

@Service
public class Scheduling1Service {

    //每2秒执行一次(若上次任务执行时间超过2秒，则立即执行，否则从上一个任务开始时算起2秒后执行本次任务)
    @Scheduled(fixedRate = 2000)
    public void test1() throws InterruptedException {
        Thread.sleep(1000L)]]></description><category></category></item><item><title><![CDATA[如何修改代码又不违背开闭原则呢？看这里]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118934812</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118934812</guid><author>dashengjava</author><pubDate>Tue, 20 Jul 2021 14:38:24 +0800</pubDate><description><![CDATA[前言
看了前一篇重构之后的代码，你可能还会有疑问：

在添加新的告警逻辑时，改动二（添加新的 handler 类）是基于扩展而非修改的方式来完成的，但改动一、三、四貌似不是基于扩展而是基于修改的方式来完成的，


那改动一、三、四不就违背了开闭原则吗？

public class Alert { // 代码未改动... }

public class ApiStatInfo {// 省略 constructor/getter/setter 方法

  private String api;

  priva]]></description><category></category></item><item><title><![CDATA[干货！终于有人把设计模式的 “里式替换原则”讲清楚了]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118799391</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118799391</guid><author>dashengjava</author><pubDate>Fri, 16 Jul 2021 14:59:40 +0800</pubDate><description><![CDATA[前言

​我们学习了 SOLID 原则中的单一职责原则和开闭原则。今天，我们再来学习 SOLID 中的 “L” 对应的原则：里式替换原则。

整体上来讲，这个设计原则是比较简单、容易理解和掌握的。今天我主要通过几个反例，带你看看，哪些代码是违反里式替换原则的？我们该如何将它们改造成满足里式替换原则？除此之外，这条原则从定义上看起来，跟我们之前讲过的 “多态” 有点类似。
如何理解 “里式替换原则”？
里式替换原则的英文翻译是：Liskov Substitution Principle，缩写为 LSP。这个原]]></description><category></category></item><item><title><![CDATA[过滤器、拦截器入门，看这一篇就够了]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118678269</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118678269</guid><author>dashengjava</author><pubDate>Mon, 12 Jul 2021 16:32:27 +0800</pubDate><description><![CDATA[实际项目开发过程中，肯定有这样的需求：


记录每个rest请求耗费的时间，入参，出参
某些请求需要判断是否有权限，某些请求是不需要权限也可以运行的


这个需求太普遍了。今天我们就一起来学习这个需求的两种实现方式：


拦截器
过滤器

拦截器
话不多说，咱们上代码，新建日志拦截器：
@Component
public class LogInterceptor implements HandlerInterceptor {
    //在请求rest接口之前调用
    @Override
    pu.]]></description><category></category></item><item><title><![CDATA[深入理解Java的继承特性]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118608463</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118608463</guid><author>dashengjava</author><pubDate>Fri, 09 Jul 2021 15:49:45 +0800</pubDate><description><![CDATA[继承（Inheritance）
学习完了Java封装和抽象两个特性，我们再来看继承特性。如果你熟悉的是类似 Java 、**C++**这样的面向对象的编程语言，那你对继承这一特性，应该不陌生了。继承是用来表示类之间的 is-a 关系，比如猫是一种哺乳动物。
从继承关系上来讲，继承可以分为两种模式，单继承和多继承。单继承表示一个子类只继承一个父类，多继承表示一个子类可以继承多个父类，比如猫既是哺乳动物，又是爬行动物。
为了实现继承这个特性，编程语言需要提供特殊的语法机制来支持，比如 Java 使用 exten]]></description><category></category></item><item><title><![CDATA[腾讯大佬总结的代码重构原则，看完再也不怕面试官问啦！]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118577372</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118577372</guid><author>dashengjava</author><pubDate>Thu, 08 Jul 2021 16:52:51 +0800</pubDate><description><![CDATA[前言

上一篇开闭原则最有用的代码改动是基于 “修改” 的方式来实现新功能的。如果我们遵循开闭原则，也就是 “对扩展开放、对修改关闭”。那如何通过 “扩展” 的方式，来实现同样的功能呢？

重构
我们先重构一下之前的 Alert 代码，让它的扩展性更好一些。重构的内容主要包含两部分：


第一部分是将 check () 函数的多个入参封装成 ApiStatInfo 类；


第二部分是引入 handler 的概念，将 if 判断逻辑分散在各个 handler 中。


具体的代码实现如下所示：
public]]></description><category></category></item><item><title><![CDATA[还在用httpclient请求接口？那你就out了]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118521412</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118521412</guid><author>dashengjava</author><pubDate>Tue, 06 Jul 2021 15:18:33 +0800</pubDate><description><![CDATA[实际项目中免不了要跟其他系统交互，那就会涉及到接口调用，如果是自己本系统的还好，可以通过打jar包引用的方式放到本项目中直接调用。

如果是其他系统的，那就需要通过远程接口调用，而远程接口调用通常使用两种方式调用

其一是webservice接口，
其二是rest接口（也就是对方给我们一个http链接地址）

本文就来讲讲如何通过rest接口调用远程服务。

在没有springboot之前，大家会想到使用httpclient去调用，没错，httpclient是一个很好的选择。但是springboot给我们.]]></description><category></category></item><item><title><![CDATA[文件这样上传，配置更灵活]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118415739</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118415739</guid><author>dashengjava</author><pubDate>Fri, 02 Jul 2021 14:57:56 +0800</pubDate><description><![CDATA[文件上传

新建一个项目，添加UploadController

@RestController

public class UploadController {

    @PostMapping("upload")
    public String post(@RequestParam("file") MultipartFile file){
        if (file.isEmpty()) {
            return "上传失败，请选择文件";
        }

      ]]></description><category></category></item><item><title><![CDATA[如何理解Java设计模式中的单一职责原则？]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118389172</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118389172</guid><author>dashengjava</author><pubDate>Thu, 01 Jul 2021 16:10:48 +0800</pubDate><description><![CDATA[我们在实际的项目过程中，如何理解Java设计模式的单一职责原则（SRP）？
我们今天要学习的是 SOLID 原则中的第一个原则：单一职责原则。
单一职责原则的英文是 Single Responsibility Principle，缩写为 SRP。这个原则的英文描述是这样的：A class or module should have a single reponsibility。如果我们把它翻译成中文，那就是：一个类或者模块只负责完成一个职责（或者功能）。
注意，这个原则描述的对象包含两个，一个是类（clas]]></description><category></category></item><item><title><![CDATA[SpringBoot启动banner，竟然还能这么玩！]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118363788</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118363788</guid><author>dashengjava</author><pubDate>Wed, 30 Jun 2021 16:17:56 +0800</pubDate><description><![CDATA[我们已经开始springboot几期了，大伙有没发现在启动工程的时候控制台会输出一段这样的东西：


那这个可以改吗，可以改的B格高一点吗，答案是肯定的，下面跟这个我来改下。

Spring Boot工程的resource目录下新建一个文本文件banner.txt用于存放自定义图案
在里面敲入 hello springboot!看下控制台的输出：



是不是变了？等等，不是说高B格吗，这个不够高。

好！满足！打开网站http://patorjk.com/software/taag，在里面敲入sprin.]]></description><category></category></item><item><title><![CDATA[Spring注解这么写，团队协作效率至少提升1倍]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118338703</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118338703</guid><author>dashengjava</author><pubDate>Tue, 29 Jun 2021 16:42:44 +0800</pubDate><description><![CDATA[@SpringBootApplication

包含@Configuration、@EnableAutoConfiguration、@ComponentScan，通常放在主类上。

@Controller

标志是一个控制器类，需要与@RequestMapping配合使用。通常做前后端分离的项目用这个注解比较少，因为后端只返回json数据结构，而不是页面。

@RestController

该注解是@Controller和@ResponseBody的组合注解





普通风格
Rest风格




@R]]></description><category></category></item><item><title><![CDATA[关于Mysql事务，你必须知道的几个知识点！]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118304536</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118304536</guid><author>dashengjava</author><pubDate>Mon, 28 Jun 2021 15:16:12 +0800</pubDate><description><![CDATA[Transaction事务

上期我们讲到了jpa的常用操作，查询、更新、删除等，但是如果在操作数据库事务时发生异常，数据会回滚吗？下面我们来看个例子

UserController新增如下代码：
@GetMapping("save1")

public String save1(){
    User user = new User();
    user.setDptId(1L);
    user.setName("a");
    user.setAge(18L);
    user.setEmai]]></description><category></category></item><item><title><![CDATA[如何优雅的实现Mysql 增删改查，看完你就会了]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118222420</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118222420</guid><author>dashengjava</author><pubDate>Fri, 25 Jun 2021 15:45:22 +0800</pubDate><description><![CDATA[接着上期说，上期没写一条sql就把数据查询出来了，那如果要保存或者更新数据怎么办呢？能不能自己写sql呢？

保存数据
@GetMapping("save")//保存数据

public void save(@RequestBody User user){
    userJpa.save(user);
}

在UserController里面添加上面的方法。使用@RequestBody接收数据，然后调用userJpa的save方法保存数据，接下来我们用postman试下。

执行之后到数据库去看下数据，.]]></description><category></category></item><item><title><![CDATA[Java程序员必备奇淫巧技篇（上）]]></title><link>https://blog.youkuaiyun.com/dashengjava/article/details/118189150</link><guid>https://blog.youkuaiyun.com/dashengjava/article/details/118189150</guid><author>dashengjava</author><pubDate>Thu, 24 Jun 2021 15:22:14 +0800</pubDate><description><![CDATA[前言
前面我们讲了Java编程过程中的命名和注释、代码风格，今天我们来讲一些比较实用的Java编程技巧，帮你切实地提高代码可读性。这部分技巧比较琐碎，也很难罗列全面，我仅仅总结了一些我认为比较关键的，更多的技巧需要你在实践中自己慢慢总结、积累。

1. 把代码分割成更小的单元块
大部分人阅读代码的习惯都是，先看整体再看细节。所以，我们要有模块化和抽象思维，善于将大块的复杂逻辑提炼成类或者函数，屏蔽掉细节，让阅读代码的人不至于迷失在细节中，这样能极大地提高代码的可读性。不过，只有代码逻辑比较复杂的时候，我们其]]></description><category></category></item></channel></rss>