1.httpClient 问题
com.apache下的包,设置超时问题:
3.x版本 :
HttpClient client = new HttpClient();
client.setConnectionTimeout(30000);
client.setTimeout(30000);
HttpClient httpClient= new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
4.3之前版本
HttpClient httpClient=new DefaultHttpClient();
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,2000);//连接时间
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,2000);//数据传输时间
4.3之后版本
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet=new HttpGet("http://www.baidu.com");
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
.setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();
httpGet.setConfig(requestConfig);
httpClient.execute(httpGet);
2.@Inherited元注解
@Inherited是一个标识,用来修饰注解
作用:如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解
注意:
接口用上个@Inherited修饰的注解,其实现类不会继承这个注解
父类的方法用了@Inherited修饰的注解,子类也不会继承这个注解
3.WebSocket session共享问题
Websocket session不可以序列号,所以只能使用发布订阅消息通知进行共享消息
基于Redis的session共享:https://blog.youkuaiyun.com/mlwsmqq/article/details/121736412
基于Rocketmq共享:https://blog.youkuaiyun.com/mlwsmqq/article/details/127673180
4.Java泛型的使用
1. 泛型介绍(JDK5 之后)
Java 中的泛型,只在编译的时候有效;在编译期,所有的泛型信息都会被擦除,List<Integer> 和 List<String> 类型在编译后,都会变成 List 类型(原始类型)
2. 泛型使用
1)泛型类public class 类名<数据类型,…> { }
示例:public class Generic<T>{ }
a.结合属性使用:private T data;
b.结合方法使用(以下两种情况都不是泛型方法):public void add(T t);
public T get(int index){
return (T)new Object();
};
2)泛型接口 修饰符 interface 接口名 <类型>{ }
示例:public interface Inter<T> { }
3)泛型方法:修饰符与返回值类型中间的 泛型标识符 <T,E,…>,是 泛型方法的标志,只有这种格式声明的方法才是泛型方法
修饰符 <类型> 返回值类型方法名(类型变量名){}
示例:public <T> void show(T t){}
public <T> T show(T t){}
public <T> T get(Object obj){
return (T)new Object();
};
//静态的泛型方法
public static <T,E> String staticMethod(T t,E e){
3. 泛型通配符的三种形式
<?> :无边界通配符(基本使用)
<? extends T> :固定上边界通配符(又称有上限的通配符)
<? super T> :固定下边界通配符(又称有下限的通配符)
4. 通配符?和泛型T、E、K、V的使用
参数之间的类型有依赖关系的,又或者返回值与参数之间有依赖关系的,使用泛型方法。
public <T> void test2(List<T> t) {}
参数之间的类型没有依赖关系的,使用通配符
public static void test(List<?> list) {}
5.mysql索引问题
https://blog.youkuaiyun.com/a6636656/article/details/124129367
https://blog.youkuaiyun.com/wpc2018/article/details/123115384
以上两个地址完美解决索引
6.@Validated和@Valid区别
1.
@Valid是使用Hibernate validation包的
@Validated是只用Spring Validator包的
ps:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现。
2.
@Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,不支持嵌套检测
@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上、,支持嵌套检测
ps1: @Valid 在java8之前注解只能标注在一个声明(如类,字段,方法)上。新增的TYPE_PARAMETER可以用来标注类型参数(定义Class的泛型校验),而TYPE_USE则可以用于标注任意类型(不包括class)例如List<@Valid User>校验User。
ps2:嵌套检测就是在一个beanA中,存在另外一个beanB属性。嵌套检测beanA同时也检测beanB
7.spring项目使用logback打印日志问题
1.注意点:
a.logback.xml与logback-spring.xml的区别:
加载顺序:logback.xml>application.yml>logback-spring.xml.
logback.xml一般用于非Spring Boot项目,logback-spring.xml用于Spring Boot项目.
logback-spring.xml可以使用<springProperty>标签读取yml配置文件中的属性值
b.bootstrap.yml不支持logback.xml或者logback-spring.xml配置,一般配置到application.yml中
c.mybatis-plus 开启与关闭 SQL 日志打印:配置第一种, 仅仅是在一个地方可以打印日志,
配置第二种, 才可以同时打印 控制台 跟 文件
# 方式一
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #不要日志打印
org.apache.ibatis.logging.slf4j.Slf4jImpl #开启日志文件SQL打印
org.apache.ibatis.logging.stdout.StdOutImpl #开启控制台 SQL 日志打印
# 方式二 application.yml 中增加配置,指定 mapper 文件所在的包
logging:
level:
com.baomidou.example.mapper: debug
2.logback多环境配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<springProperty scope="context" name="applicationName" source="spring.application.name"/>
<!-- 单个日志文件的大小 -->
<springProperty scope="context" name="maxFileSize" source="logging.file.max-size" defaultValue="20MB"/>
<!-- 日志保留时长 (天) -->
<springProperty scope="context" name="maxHistory" source="logging.file.max-history" defaultValue="30"/>
<!-- 日志文件路径 -->
<springProperty scope="context" name="log.path" source="logging.path" defaultValue="/logs/${applicationName}"/>
<contextName>${applicationName}</contextName>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID:- }) %clr(---){faint} %clr([%10t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex"/>
<!-- 默认日志输出格式 -->
<property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } --- [%t] %-40.40logger{39} : %m%n%wex"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder" charset="UTF-8">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
<!--日志打印所有级别-->
<!--
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ALL</level>
<onMatch>NEUTRAL</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
-->
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,这里设置为20MB -->
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 开发环境和测试环境,日志输出到控制台 -->
<springProfile name="dev|test">
<!--控制台和日志文件输出级别-->
<root level="INFO">
<appender-ref ref="console"/>
</root>
</springProfile>
<!-- 生产环境,日志输出到文件 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</springProfile>
</configuration>
8.HashMap和ConcurrentHashMap
前者线程不安全,key和value均可以为null
后者线程安全,key和value均不可以为null,因为多线程下可能会引起歧义;
ConcurrentHashMap:
map.get("key")+1;map.put("key",val);此时线程也不安全,因为两步不是原子操作
9. 在 Java 中,如何跳出当前的多重嵌套循环
/定义一个标号 ok:
ok:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
break ok;
}
}
}
10.GC调优
1.尽量让对象在新生代就被回收,防止过多的对象晋升到老年代,减少大对象的分配
2.使用arthas观察GC的实际情况,修改JVM参数,
比如说,堆的大小xms xmx;使用G1收集器等
3.遇到问题,arthas导出dump文件使用MAT工具分析并定位问题对象