首页 > 其他分享 >随笔

随笔

时间:2024-05-28 16:23:25浏览次数:24  
标签:String 观察者 模式 static new 随笔 public

问题

  1. String带小数转long类型

    Double doubleTime = Double.parseDouble("22.1");
    long longTime = doubleTime.longValue();
    
  2. linux从一台机器复制文件到另一台机器

    # 从有文件的机器复制到目标机器10.51.207.55
    # scp 源文件路径 root@目标机器IP:目标文件路径
    scp /root/software/influxdb-1.7.6_linux_amd64.tar.gz [email protected]:/root/software
    
  3. word模板展示图片 需要转换成base64

    public ImageEntity getImageBase64(String imageUrl) {
        if (ObjectUtils.isEmpty(imageUrl)) {
            return null;
        }
        URL url = null;
        InputStream is = null;
        ByteArrayOutputStream outputStream = null;
        HttpURLConnection httpUrl = null;
        try {
            url = new URL(imageUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            is = httpUrl.getInputStream();
            outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = is.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            byte[] fileBytes = outputStream.toByteArray();
            if (null != fileBytes) {
                //获取图片的真实高度和宽度
                ImageIcon imageIcon = new ImageIcon(fileBytes);
                int height = imageIcon.getIconHeight();
                int width = imageIcon.getIconWidth();
                //超过页面宽度,进行等比例缩放
                int pageWidth = 630;
                if (width > pageWidth) {
                    height = height * pageWidth / width;
                    width = pageWidth;
                }
                ImageEntity image = new ImageEntity();
                image.setHeight(height);
                image.setWidth(width);
                image.setData(fileBytes);
                image.setType(ImageEntity.Data);
                return image;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (httpUrl != null) {
                httpUrl.disconnect();
            }
        }
        return null;
    }
    
  4. 保留两位小数点

    String.format("%.2f","20.123358");
    /**
    BigDecimal.setScale()方法用于格式化小数点,setScale(1)表示保留一位小数,默认用四舍五入方式
    setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35变成2.3
    setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4
    setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
    setScale(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍
    */
    new BigDecimal("20.123358").setScale(2,BigDecimal.ROUND_HALF_UP);
    
  5. 截取字符串中的数字

    public static String getNumber(String str){
         Matcher m2 = Pattern.compile(".*\\d").matcher(str);
         return m2.find()?m2.group():"";
     }
    
  6. IDEA项目启动问题

    • SLF4J: Class path contains multiple SLF4J bindings.
    问题原因:项目中引入的依赖有多个slf4j的实现,导致多个slf4j实现的依赖冲突
    解决方案:
    	* 如果项目中有使用logback日志,那么不推荐排除logback-classic的依赖。
    	* 下载一个Maven Helper的IDEA插件,作用是可视化分析pom文件引入的依赖。
    	* 每个pom文件都查找重复依赖并exclue
    	* 清除一下maven并重新刷新依赖
    	* 重新启动springboot项目
    
    
    • Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata
    问题原因:springboot版本和springcloud版本不一致导致的
    解决方案:
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-dependencies</artifactId>
         <version>2.3.7.RELEASE</version>
         <type>pom</type>
         <scope>import</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR9</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    
  7. springboot配置文件区分开发和生产环境 配置编写

    • bootstrap.yml 配置文件
    server:
    	port: 8081
    	servlet:
    		context-path: /ptp
    		shutdown: graceful
    spring:
    	application:
    		name: ptp-admin
    	profiles:
    		active: prod
    
    • bootstrap-dev.yml 配置文件
    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 10.51.200.58:8848
          config:
            server-addr: 10.51.200.58:8848
            file-extension: yml
            shared-configs:
              - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
    
    • bootstrap-prod.yml 配置文件
    spring:
      cloud:
        nacos:
          discovery:
            server-addr: 10.55.42.175:8848
          config:
            server-addr: 10.55.42.175:8848
            file-extension: yml
            shared-configs:
              - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
    
  8. 两个string比较大小

    1. str1.compareTo(str2)
    只有相同位数的字符串可以使用compareTo方法进行比较,否则需要转换成int/long/BigDecimal类型进行比较
    2. 转换成BigDecimal比较 str1>=str2 返回true 
    new BigDecimal(str1).compareTo(new BigDecimal(str2)) >= 0
    
  9. 时间格式转换

    1. 带毫秒的时间格式转换
    Date date1 = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss.SSS", "2024-04-10 11:41:02.043");
    Date date2 = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss.SSS", "2024-04-10 11:41:02.045");
    System.out.println(date1);
    System.out.println(date2);
    System.out.println((date2.getTime() - date1.getTime()) * 0.001); 
    
    1. 日期型字符串转日期型格式
    private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
                "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM","yyyy-MM-dd HH:mm:ss.SSS"}; 
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return DateUtils.parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }
    
  10. 前后端跨域问题

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry){
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowedMethods("POST","GET","DELETE","PUT","OPTIONS")
                .maxAge(3600)
                .allowCredentials(true);
    }
}
  1. 413 Request Entity Too Large(请求实体太大)

    原因:可以看请求body的大小 Content-Length显示 nginx默认的request body为1M
    解决方案:nginx.conf配置文件中设置 http{}中加入client_max_body_size,然后重启nginx
    systemctl restart nginx
    
  2. IOException

    # 1. 报错说明
    做压力测试的时候遇到的这个问题,并发数量低的情况下不会出现这个问题。
    服务器前端通过nginx不断的和后端的java服务器建立连接,当并发上来之后,nginx不断的和后端的java服务器建立连接。虽然做了keep-alive配置,却依然挡不住连接的销毁和创建。
    # 2. 查看超时情况
    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}'
    发现TIME_WAIT 数量非常高,也就是nginx这台服务器主动断开连接,导致java后端往断开套接字上写数据,于是就报错。
    # 3. 解决方案
    修改nginx所在服务器的/etc/sysctl.conf文件,服务器能够快速回收和重用那些TIME_WAIT的资源
    vim /etc/sysctl.conf
    
    配置内容:
    # 表示开启SYN Cookies 当出现SYN等待队列溢出时,启用cookies来处理,可防止少量SYN攻击,默认为0 表示关闭
    net.ipv4.tcp_syncookies = 1
    # 表示开启重用,允许将TIME_WAITsockets重新用于新的TCP连接,默认为0, 表示关闭
    net.ipv4.tcp_tw_reuse = 1
    # 表示开启TCP连接中TIME_WAIT sockets的快速回收,默认0 表示关闭
    net.ipv4.tcp_tw_recycle = 1
    # 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN_WAIT_2状态的时间
    net.ipv4.tcp_fin_timeout = 30
    
    生效命令
    /sbin/sysctl -9
    # 4. 结果
    TIME_WAIT 降低到正常范围100以下,java程序正常
    
  3. mybatis中saveOrUpdate更新字段 不能将属性置空

    saveOrUpdate属性值为空 将被忽略掉,不进行更新;如果设置不忽略 不需要修改的属性会默认置为空
    可以使用LambdaUpdateWrapper方法
    OceanBase数据库ID无法自增,可设置ID为IdUtil.getSnowflakeNextId()
    

设计模式

创建型模式

关注对象的创建 ,同时隐藏创建逻辑:工厂模式、抽象工厂模式、单利模型、建造者模式、原型模式

1. 单例模式

  • 单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例

  • 优点:不会频繁的创建和销毁对象,浪费系统资源

  • 使用场景:IO、数据库连接、Redis连接等

单例模式的代码实现

/**
 * 单例模式 保证一个对象只存在一个实例,优点是可以避免频繁的创建和销毁对象,避免浪费系统资源
 */
public class SingleMain {
    public static void main(String[] args) {
        // 单例模式 直接返回对象
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);

        // 单例模式的延迟加载
        SingletonLazy instance1 = SingletonLazy.getInstance();
        SingletonLazy instance2 = SingletonLazy.getInstance();
        System.out.println(instance1 == instance2);

    }
    // 单例模式 在类加载的时候就创建了,会影响程序的启动速度,需要使用单例模式的延迟加载
    static class Singleton {
        private static Singleton instance = new Singleton();
        public static Singleton getInstance(){
            return instance;
        }
    }
    // 单例模式的延迟加载 使用synchronized保证线程安全  区分懒汉式和饿汉式
    static class SingletonLazy {
        private static SingletonLazy instance;
        public static synchronized SingletonLazy getInstance(){
            if (instance == null) {
                instance = new SingletonLazy();
            }
            return instance;
        }
    }
}

2. 简单/抽象工厂模式

public class FactoryMain {
    public static void main(String[] args) {
        // 简单工程模式
        String latte = Factory.createProduct("Latte");
        System.out.println(latte);

        // 抽象工厂模式
        String latte1 = new CoffeeFactory().createProduct("Latte");
        System.out.println(latte1);
        String teacher = new WorkerFactory().createProduct("Teacher");
        System.out.println(teacher);

    }
    /**
     * 简单工厂模式,工厂类含有必要的逻辑判断,客户端不需要知道所创建的具体产品类的类型,只需要知道具体产品类对应的参数即可。
     * 优点:对于一些复杂的类名,通过简单工厂模式,可以减少使用者的记忆量;
     * 通过引入配置文件,在不改变任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性
     * 缺点:不易扩展,一旦添加了新的产品类型,就需要修改工厂的创建逻辑,产品类型较多时,不利于系统的维护
     */
    static class Factory {
        public static String createProduct(String product) {
            String result;
            switch (product) {
                case "Mocca":
                    result = "摩卡";
                    break;
                case "Latte":
                    result = "拿铁";
                    break;
                default:
                    result = "其他";
                    break;
            }
            return result;
        }
    }

    /**
     * 抽象工厂模式 通过继承的方式,只声明方法,具体的实现交给子类去实现,可扩展性强
     */
    static abstract class AbstractFactory {
        public abstract  String createProduct(String product);
    }
    static class WorkerFactory extends AbstractFactory {
        @Override
        public String createProduct(String product) {
            String result;
            switch (product) {
                case "IT":
                    result = "IT工作者";
                    break;
                case "Teacher":
                    result = "教师";
                    break;
                default:
                    result = "其他工作者";
                    break;
            }
            return result;
        }
    }
    static class CoffeeFactory extends AbstractFactory{
        @Override
        public String createProduct(String product) {
            String result;
            switch (product) {
                case "Mocca":
                    result = "摩卡";
                    break;
                case "Latte":
                    result = "拿铁";
                    break;
                default:
                    result = "其他";
                    break;
            }
            return result;
        }
    }
}

结构性模式

关注类和对象之间的组合:适配器模式、过滤器模式、装饰模式、享元模式、代理模式、外观模式、组合模式、桥接模式

1. 装饰器模式 - 包装模式Wrapper

* 装饰器模式的作用:
1. 用来动态的为一个对象增加新的功能,装饰模式是一种用于代替继承的技术。无需通过继承增加子类就能扩展对象的新功能。

* 装饰器模式的应用:
1. mybatis的缓存模块cache
2. IO流中的FileInputStream和FileOutputStream
3. spring的中各种Wrapper

* 装饰模式和代理模式的区别:
1. 装饰器模式强调的是增强自身;代理模式是为了实现对象的控制,让别人做一些本身和业务没有太多关系的职责(记录日志,设置缓存等)
2. 装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式是给对象提供一个代理对象,并由代理对象控制对原有对象的引用
3. 装饰模式是为了增强对象的功能;代理对象是对代理的对象施加控制,但不对对象本身的功能进行增强。

2. 代理模式


行为型模式

关注对象之间的通信:责任链模式、命令模式、中介模式、观察者模式、状态模式、策略模式、模板模式、空对象模式、备忘录模式、迭代器模式、解释器模式、访问者模式

1. 观察者模式

​ 观察者模式又叫发布-订阅模式,模型-视图模式,源-监听器模式。从属者模式

​ 观察者模式 是定义对象间的一种一对多依赖关系,每当一个对象状态发生改变时,相应的依赖对象都会得到通知并自动更新。

  • 优点

    1. 观察者模式实现了表示层和数据层的分离,抽象了接口,定了稳定的消息更新传递机制,可以有各种各样不同的表示层作为具体观察者角色
    2. 观察者模式在观察目标和观察者之间建立了一个抽象的耦合;
    3. 观察者模式支持广播通信;
    4. 观察者模式符合开闭原则,对拓展开放,对修改关闭
    
  • 缺点

    1. 如果一个观察目标有多个直接和间接的观察者,将所有观察者都通知到会花费很长时间;
    2. 如果观察者和观察目标之前有循环依赖的话,可能导致系统崩溃;
    3. 观察者模式并没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化
    
  • 观察者模式中的角色

    1. Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
    2. ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
    3. Observer:抽象观察者,是观察者的抽象类,定义了一个更新接口,使得在得到主题更改通知时更新自己。
    4. ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身状态。
    
  • 代码实现

    /**
     * 定义观察者 消息接收方
     */
    public interface ObServer {
        public void update(String message);
    }
    class ConcrereObserver implements ObServer{
        private String name;
        public ConcrereObserver(String name) {
            this.name = name;
        }
        @Override
        public void update(String message) {
            System.out.println(name + ":"+message);
        }
    }
    
    /**
     * 定义被观察者 消息发送方
     */
    public interface Subject {
        // 增加订阅者
        public void attach(ObServer obServer);
        // 删除订阅者
        public void detach(ObServer obServer);
        // 通知订阅者更新消息
        public void notify(String message);
    }
    
    /**
     * 具体被观察者 消息发布方
     */
    class ConcreteSubject implements Subject {
        // 订阅者列表 存储信息
        private List<ObServer> list = new ArrayList<>();
    
        @Override
        public void attach(ObServer obServer) {
            list.add(obServer);
        }
    
        @Override
        public void detach(ObServer obServer) {
            list.remove(obServer);
        }
    
        @Override
        public void notify(String message) {
            for (ObServer obServer : list) {
                obServer.update(message);
            }
        }
    }
    
    public class ObserverMain {
        public static void main(String[] args) {
            // 定义发布者
            ConcreteSubject subject = new ConcreteSubject();
            // 定义订阅者
            ConcrereObserver observer1 = new ConcrereObserver("老王");
            ConcrereObserver observer2 = new ConcrereObserver("java");
            // 添加订阅
            subject.attach(observer1);
            subject.attach(observer2);
            // 发布消息
            subject.notify("更新了");
        }
    }
    

GIT

  1. 命令使用

    1. clone新地址代码 拉取到本地
    	git clone http:XXXXX
    2. 创建新分支 提交到远程新分支
    	git branch XXX
    	git branch --set-stream-to=origin/XXX
    	git push 
    	git pull
    3. 查看所有分支
    	git branch -a
    4. 提交代码
    	git add .
    	git commit -m '备注描述' 
    	git push origin XXX
    5. 切换分支
    	* 切换到已有分支  git checkout XXX
    	* 拷贝远程分支到本地,并重新命名:git checkout -b newBranch origin/master
    6. 合并分支
    	git merge XXX
    7. 刪除分支
    	刪除本地分支 git branch -d xxx  强制删除用-D
    	刪除远程分支 git push origin --delete xxx
    
    

数组

HashMap

ArrayList

JVM

JVM调优

垃圾回收

Java多线程

线程池

@Configuration
public class ThreadPoolConfig {
	// 核心线程池大小
	private int corePoolSize = 50; 
	// 最大可创建的线程数
	private int maxPoolSize = 200; 
	// 队列最大长度
	private int queueCapacity = 10000; 
	// 线程池维护线程所允许的空闲时间
	private int keepAliveSeconds = 300; 
	@Bean(name = "atpThreadPoolTaskExecutor")
	public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setMaxPoolSize(maxPoolSize);
		executor.setCorePoolSize(corePoolSize);
		executor.setQueueCapacity(queueCapacity);
		executor.setKeepAliveSeconds(keepAliveSeconds);
		// 线程池对拒绝任务(无线程可用)的处理策略
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		return executor;
	} 
}
@Component
public class AsyncRunner { 
    private final Logger logger = LoggerFactory.getLogger(getClass()); 
    @Async("atpThreadPoolTaskExecutor")
    public void run(RunnerCallback callback) {
        logger.debug("AsyncRunner is calling by RunnerCallback mode.");
        try {
            callback.call();
        } catch (ParseException e) {
            logger.error("异步调用报错",e);
        }
    } 
    @Async("atpThreadPoolTaskExecutor")
    public <V> Future<V> run(ReturnRunnerCallback<V> callback) {
        logger.debug("AsyncRunner is calling by ReturnableRunnerCallback mode.");
        return AsyncResult.forValue(callback.call());
    }
}

Dubbo

Redis

命令行

  1. 数据库操作
# 测试是否连通
ping
# 切换数据库
select index
# 数据移动
move key db
# 显示数据总量
dbsize
  1. 健值操作
# 查看当前库的所有key
keys *
# 删除指定key
del key
# 获取key是否存在
exists key
# 获取key的类型
type key
# 指定key的有效期 以s为单位返回
ttl key

  1. 数据类型

配置文件

  1. redis.conf各个参数
# 指定redis只接收来自该IP地址的请求  默认不开启
bind 10.51.200.58
# 当主数据库连接需要密码验证时,在这里设置
masterauth "123456" 
# 开启这个参数需要指定bind和密码
protected-mode yes
# redis的默认端口6379
port 6379
tcp-backlog 511
# 设置客户端连接时的超时时间,单位秒 当客户端在这段时间内没有发出任何指令,那么关闭该连接
timeout 0
# 指定TCP连接是否为长连接,“侦探”信号有server端维护,默认0表示禁用
tcp-keepalive 300
# 默认情况下redis不是在后台运行的,如果需要后台运行 需要改成yes
daemonize yes
 
supervised no
# redis后台运行时,默认把pid文件放到/var/run/redis.pid,可配置到其他位置,当运行多个redis服务时,需指定不同的
pidfile "/var/run/redis_6379.pid"

# log等级分为4级,debug、verbose、notice、warning 生产环境下一般开启notice
loglevel notice
# 配置log文件地址 默认 logfile stdout
logfile "/opt/logs/6379.log"

# 设置数据库个数 默认16个库,默认使用0库 可用select命令切换数据库
databases 16

always-show-logo yes

# 保存数据快照的频率,数据持久化到dump.rdb文件,多少秒期间至少多少个变更操作出发snapshot数据保存动作
save 900 1
save 300 10
save 60 10000  

# 持久化出现错误时,是否继续进行工作,是否终止所有客户端write请求。 默认yes表示终止
stop-writes-on-bgsave-error yes
# 数据进行镜像备份时,是否启用rdb文件压缩手段,默认res。压缩可能需要额外的CPU开支,不过能够有效的缩小rdb文件的大小,有利于存储/备份/传输/数据恢复
rdbcompression yes
# 读写操作时,都会损失10%的性能是否进行校验和对rdb文件使用CRC64校验,默认yes,那么每个rdb文件内容末尾都会追加CRC校验,有利于第三方校验工具检测文件完整性
rdbchecksum yes
 
 
# 镜像备份文件的文件名,默认dump.rdb
dbfilename "dump-6379.rdb"
# rdb/aof文件存储位置
dir "/opt/data/redis"
 
# 设置该数据库为其他数据库的从数据库,并为其指定master信息
# slaveof masterip masterport

# 当主master服务器挂机或主从复制在进行时,是否允许客户访问可能过期的数据,在yes情况下,slave继续向客户端提供只读服务,有可能此时的数据已经过期;在no的情况下,任何向此server发送的请求服务都会被告知“error
slave-serve-stale-data yes
# slave是否为只读,强烈建议yes
slave-read-only yes
# slave向指定master发送ping消息的时间间隔秒 默认10
repl-ping-slave-period 10
# slave与master通讯中,最大空闲时间,默认60秒,超时将导致连接关闭
repl-timeout 60
# 
repl-diskless-sync no
 
repl-diskless-sync-delay 5
# slave与master连接 是否禁用TCP nodelay. yes表示禁用,socket通讯中数据以packet方式发送(packet大小受buffer限制),小数据可能会受buffer影响,不会立即发送,可能存在延迟;no选项,任何数据都会被立即发送,及时性好,效率低,建议设为no
repl-disable-tcp-nodelay no
# slave权重值,使用Sentinel模块,master失效后,sentinel会将slave列表中找到权重最低>0的slave,提升为master,如果权重值为0,此slave为观察者,不参与master选举
slave-priority 100
# 设置客户端连接后进行任何其他指定前需要使用密码
requirepass "123456"
# 默认情况下,redis会在后台异步吧数据库镜像备份到磁盘,但是备份耗时,不能频繁。所以开启appendOnly后,redis会把接收到每一次请求追加到appendonly.aof文件中,当redis重启时,会从该文件恢复到之前的状态
appendonly no
# AOF的文件名
appendfilename "appendonly.aof"
# AOF文件同步的频率 everysec对写操作累积,每秒同步一次;no不主动同步;always每次写操作都同步
appendfsync everysec 
# 在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,默认no,表示不暂缓,新aof记录仍然会被立即同步 
no-appendfsync-on-rewrite no
# 当aof log增长超过指定比例时,重写log file,设置为0表示不自动重写aof日志
auto-aof-rewrite-percentage 100
# 触发aof rewrite的最小文件尺寸
auto-aof-rewrite-min-size 64mb
aof-rewrite-incremental-fsync yes
aof-load-truncated yes 
aof-use-rdb-preamble no
# lua脚本运行的最大时间
lua-time-limit 5000
# 慢操作日志记录,单位微秒 如果操作超过此值,会把command信息保存到内存,设置0表示记录全部操作
slowlog-log-slower-than 10000
# 慢操作保存的最大条数,如果超过次条数,旧队列将被移除
slowlog-max-len 128
# ziplist中允许存储的最大条目数,超过自动转换成hashTable(redis中默认对hash类型使用ziplist存储)
hash-max-ziplist-entries 512
# ziplist中允许value值得最大字节数,默认64 建议1024
hash-max-ziplist-value 64
# zset为有序集合,ziplist和skiplist,数据较多时,会被重构为skiplist
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0 
set-max-intset-entries 512
# 客户端buffer控制
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# 执行后台任务的频率,默认10,值越大表示redis对间歇性task的执行次数越频繁,间歇性task包括过期集合检测,关闭空闲超时连接等,此值必须大于0且小于500,建议采用默认值
hz 10

lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no
  
latency-monitor-threshold 0 
notify-keyspace-events "" 
hll-sparse-max-bytes 3000 
activerehashing yes 
slaveof 10.51.200.58 6380

常见问题

  1. redis常见的数据格式
    1. list存储的数据较大 如何处理
  2. redis缓存击穿 穿透 雪崩
  3. redis分布式索

集群

SQL

函数

1. string转数字取最大  max(to_number(xxx))
2. 

mybatsis

  1. mybatis的if else

    select * from user 
    <if test = "id != null">
        where id = #{id}
    </if>
    
    select * from user
    <choose>
    	<when test="id != null">
            and id = #{id}
        </when>
        <otherwise>
        	and id is null
        </otherwise>
    </choose>
    

MySQL

  1. mysql底层数据
  2. 索引的优化

InfluxDB

  1. influxdb 时序性数据库

  2. influxdb连接

    @Component
    @ConfigurationProperties(prefix = "influxdb")
    public class InfluxDBInfoStatic {
    	private static String url;
    	private static String port;
    	private static String database;
    	private static String measurement;
    	private static String user;
    	private static String password;
    	private static String retentionPolicy="hour";
    	//okhttpclient连接池最大空闲数量
    	private static Integer idleConnectionCount=100;
    	//okhttpclient连接池最大空闲保持时间
    	private static Integer keepAliveDuration=10;
    }
    @Slf4j
    public class InfluxDBConnectionUtil {
    	private static final InfluxDB INFLUXDB;
    	private final static ConnectionPool connectionPool=new ConnectionPool(InfluxDBInfoStatic.getIdleConnectionCount(),InfluxDBInfoStatic.getKeepAliveDuration(), TimeUnit.SECONDS);
    	static{
    		OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient().newBuilder()
    				.connectTimeout(30, TimeUnit.SECONDS)
    				.writeTimeout(30, TimeUnit.SECONDS)
    				.retryOnConnectionFailure(true)
    				.readTimeout(30, TimeUnit.SECONDS);
    		okHttpClientBuilder.connectionPool(connectionPool);
    		INFLUXDB = InfluxDBFactory.connect(
    				"http://" + InfluxDBInfoStatic.getUrl() + ":" + InfluxDBInfoStatic.getPort()
    				, InfluxDBInfoStatic.getUser(), InfluxDBInfoStatic.getPassword(),okHttpClientBuilder);
    	} 
        /**
         * 获取对象句柄
         */
        public static InfluxDBConnectionUtil getInstance() {
            return SingletonInstance.INSTANCE;
        }
      
    	/**
    	 * 创建自定义保留策略 policyName-策略名;days-保存天数;replication-保存副本数量;isDefault-是否设为默认保留策略          
    	 */
    	public void createRetentionPolicy(String dataBaseName, String policyName, int days, int replication, Boolean isDefault) {
    		String sql = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %sd REPLICATION %s ", policyName, dataBaseName, days, replication);
    		if (isDefault) {
    			sql = sql + " DEFAULT";
    		}
    		query(sql);
    	}
    
    	/**
    	 * 创建默认的保留策略 策略名:hour,保存天数:30天,保存副本数量:1,设为默认保留策略
    	 * 
    	 */
    	public void createDefaultRetentionPolicy() {
    		String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT", "hour", InfluxDBInfoStatic.getDatabase(), "30d", 1);
    		this.query(command);
    	}
    
    	/**
    	 * 查询 
    	 */
    	public QueryResult query(String command) {
    		return INFLUXDB.query(new Query(command, InfluxDBInfoStatic.getDatabase()));
    	}
    
    	/**
    	 * 插入 measurement-表;tags-标签;fields-字段
    	 */
    	public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields, long time, TimeUnit timeUnit) {
    		Builder builder = Point.measurement(measurement);
    		builder.tag(tags);
    		builder.fields(fields);
    		if (0 != time) {
    			builder.time(time, timeUnit);
    		}
    		INFLUXDB.write(InfluxDBInfoStatic.getDatabase(), InfluxDBInfoStatic.getRetentionPolicy() == null || InfluxDBInfoStatic.getRetentionPolicy().equals("") ? "autogen" : InfluxDBInfoStatic.getRetentionPolicy(), builder.build());
    	} 
    	public static void main(String[] args) {
    		QueryResult results = InfluxDBConnectionUtil.getInstance()
    				.query("select time, application, avg, count, countError, max, min, \"pct90.0\", \"pct95.0\", \"pct99.0\", rb, sb, transaction from jmeter where application = '16'");
    		QueryResult.Result oneResult = results.getResults().get(0);
    		if (oneResult.getSeries() != null) {
    			List<List<Object>> valueList = oneResult.getSeries().stream().map(QueryResult.Series::getValues).collect(Collectors.toList()).get(0);
    			if (valueList != null && valueList.size() > 0) {
    				System.out.println("valueList ===> " + JSONUtil.toJsonStr(valueList));
    				for (List<Object> value : valueList) {
    					System.out.println("value ===> " + JSONUtil.toJsonStr(value)); 
    				}
    			}
    		}
    	}
    }
    

Linux

Linux命令

# 查找文件
find / -name XXX
# 递归查找文件和文件夹
ls -R -l | grep XXX
# 查看启动端口
ps -ef|grep xxx.jar
# 查看日志 
1. cat 查看所有
2. more 分屏展示  /word 搜索word字符串
3. tail -f XXX  取出文件后几行 侦测展示
4. head -n xxx 取出文件前面几行
例如:
查看第100行前面3行数据 more +100 | head -3  
查看第100行后边3行数据 more +100 | tail -3
# 查看磁盘使用情况
df -h



spring

spring框架

spring是一个轻量级的框架,没有框架之前需要手动创建对象,设置对象属性等。

springboot启动

微服务

springcloud组件

DDD领域驱动模型

分布式

分布式事务

nacos

  1. nacos热部署是怎么配置的

标签:String,观察者,模式,static,new,随笔,public
From: https://www.cnblogs.com/zrx1/p/18216123

相关文章

  • AE开发随笔
    新建一个GIS程序创建程序窗体应用  首先,在VS中新建一个基于VisualC#的windows窗体应用程序添加可视化控件  我们会看到一个空白的窗体,但一个我们要创建的是GIS程序,那肯定不能少了地图、菜单栏、工具条、状态栏······  VS的工具箱中就提供了各种工具来帮我们......
  • 高级算法随笔
    高级算法高级算法是C++编程中非常重要的一个方面,它涉及到各种复杂的数据结构和算法设计。比如,常见的高级算法包括动态规划、图论算法、搜索算法等等。在C++中,我们可以利用各种数据结构和STL(StandardTemplateLibrary)来实现这些算法,同时也可以自行设计和优化算法以提高......
  • 阅读相关文章的随笔
    1、Quora精选:为什么软件开发周期总是预估的2~3倍?https://www.sohu.com/a/132411358355123(已失效)软件开发涉及到技术、人员、管理等多个方面,任何一个环节的不确定性都可能导致时间线拉长。因此,项目管理者和团队成员需要对可能出现的风险有所准备,并通过灵活的项目管理和有效的沟......
  • 期中考试后随笔
    Part0前言Whenweweresoyoung我梦到当时我们翻过墙曼陀罗花沿途绽放我们光脚越过人间荒唐Wearestupidbutstrong放学的屋顶像万人广场从不多想只是信仰少年回头望笑我还不快跟上——五月天《成名在望》Part-I离别舍不得Wrose,潇寞,Qwehhh,viki617的离别我们曾......
  • 5.20随笔
    Ubuntu下安装OpenSSHServer可以使用命令行安装openSSHServer:sudoapt-getinstallopenssh-server随后,ubuntu会自动下载并安装opensshserver,并一并解决所有依赖关系.我们也可以通过UbuntuSoftwareCenter,搜索"openssh-server",然后点安装就好了/下面介绍在window......
  • 自动获取随笔链接(用于博客签名或者版权信息)
    今天弄了好久也不知道怎样自动获取每篇文章对应的链接,就在这时,突然发现博客签名里面有一个模板选项,下拉有个转载声明选择框,如下:点完之后,出现了我想要的东西!!这不就是我心心念念、苦苦寻找的自动获取文章链接函数吗?!<p>本文来自博客园,作者:{author},转载请注明原文链接:{post_url......
  • Day01学习随笔
    Day01学习随笔记录我的学习之旅常用的Dos命令盘符切换直接输入希望进入的盘符+:。(用英文版":")查看当前目录下所有文件 dir切换目录 cd(不能跳转到另一个盘符内的文件夹,只有先跳转到相应的盘符,才能进入对应的目录)返回上级目录 cd..清理屏幕......
  • 随笔-网络-Linux多网卡同网段解决方法(配置IP路由)
    系统配置:多网口情况下,假设各个网口ip在同一网段;此时,由于默认路由规则,从不同网口的ip访问,服务器依旧会返回默认网口的mac地址,配置方式如下:sysctl-wnet.ipv4.ip_forward=1#开启ip转发规则net.ipv4.conf.X.rp_filter=0#X填alldefault各个网卡路由设置:假设默认网卡......
  • 随笔-调试-数据库常用命令
    目录Mysql命令登录命令在命令行直接执行命令查看表数据/修改表数据/清空数据查看表结构/增加列/删除列/删除表wireshark抓mysql的报文Redis命令登录并执行命令/查看数据批量删除数据sqlite命令Mysql命令登录命令mysql-uroot-p'root'-h127.0.0.1-P3360xxxDb在命令行直接......
  • 随笔-aliyun os centos 9 docker-ce install
    aliyunoscentos9docker-ceinstallsudowget-O/etc/yum.repos.d/docker-ce.repohttps://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.reposudoyum-yinstalldocker-ce参考:InstallDockerEngineonCentOS阿里云文档《安装Docker并使用(Linux)》(来自......