Java实际工作tips

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. 通配符?和泛型TEKV的使用
	参数之间的类型有依赖关系的,又或者返回值与参数之间有依赖关系的,使用泛型方法。
	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工具分析并定位问题对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有什么是应该

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值