各种JAVA JDK的镜像分发:https://www.injdk.cn/
java是值传递还是引用传递
首先要明确知道什么是值传递,什么是引用传递;
1 |
void doSth(Object *obj) { |
我们根据上面这段代码来说一下两种传递时,1、2分别包含什么操作:
- 值传递:
doSth
传递的是对象o
的内存,在doSth
函数内部生成了obj
的栈内存指向了o
的内存地址,
所以改变了obj
的值,不会影响外面o
的指向,用图表示:
- 引用传递:传递的是别名,参数表示的地址和内存都一样,用图表示:
如何判断是值传递还是引用传递,只需要看在函数中,传进来的参数在重新赋值的情况下,是否会改变原参数,比如:
1 |
void doSth(Object *obj) { |
参考:https://blog.fearcat.in/a?ID=00650-2bba8274-4da2-415e-ab26-5713820b1d25
最后,我们思考另外一个问题,为什么java 里没有指针?
java里为什么没有指针?
java认为:
- 开发人员应该更多的关注业务代码,尽量帮你完成不需要关注的操作:指针管理、内存管理;
- 稳定问题,容易出现指针越界(指针指向的是地址,可以前后移动)
- 安全问题(可能是因为指针可以指向任意内存地址?)
<Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name ‘xxx’ defined in class path resource [xxx]
- 问题
<Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name ‘xxx’ defined in class path resource [xxx]: Cannot register bean definition [Root bean: class [null]; scope=refresh; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=redisTicketRegistryConfiguration; factoryMethodName=ticketRegistry; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/apereo/cas/config/RedisTicketRegistryConfiguration.class]] for bean ‘scopedTarget.ticketRegistry’: There is already [Root bean: class [null]; scope=refresh; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=casCoreTicketsConfiguration; factoryMethodName=ticketRegistry; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/apereo/cas/config/CasCoreTicketsConfiguration.class]] bound.>
- 问题溯源
org/springframework/spring-beans/5.2.12.RELEASE/spring-beans-5.2.12.RELEASE-sources.jar!/org/springframework/beans/factory/support/DefaultListableBeanFactory.java:944
- 解决
spring.main.allow-bean-definition-overriding: true
[org.springframework.boot.context.logging.ClasspathLoggingApplicationListener] –
- 问题
spring-boot 项目无法启动,无错误提示
- 解决思路
我们找到 Application failed to start with classpath: unknown
这句话提示的位置,
/Users/sucre/.m2/repository/org/springframework/boot/spring-boot/2.3.7.RELEASE/spring-boot-2.3.7.RELEASE-sources.jar!/org/springframework/boot/context/logging/ClasspathLoggingApplicationListener.java:54
打个断点,发现 event 有个 Exception 变量,可以查到具体的原因,手动执行 e.printStackTrace();
就能找出原因所在了
- 解决
至于我的问题是,yaml 配置有问题,而且找了很多遇见这种问题的同学,基本都是 yaml 配置错误
VisualVM
如何连接远程 K8S 中的服务
jVisualVM
=VisualVM
-
首先修改服务启动参数:
““
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=[port]
-Dcom.sun.management.jmxremote.rmi.port=[port]
-Djava.rmi.server.hostname=localhost1
2
3
4
5
6
7
> `-Djava.rmi.server.hostname` 是否一定要 `localhost` ?
2. 如果无法直连 K8S,则开启端口转发
```shell script
kubectl --kubeconfig [config-file] port-forward svc/[service] [port:port] -n [namespace] -
配置
visualvm
文件(F) ->
添加JMX
连接… ->
输入 127.0.0.1:[port]
see: JMX – 远程监控JVM
DDD开源项目
内联
inlining: 内联,比如user.getName() 会被优化为 user.name
java中针对内联的优化:https://blog.csdn.net/yunxizixuan/article/details/80905086
优缺点:https://xduwq.blog.csdn.net/article/details/106652218(不知道不同语言是否想通)
JVM优化(20210816)
java -Xms2048m -Xmx2048m -Xmn1228m -XX:SurvivorRatio=5 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Xss512K -XX:+DisableExplicitGC -XX:+UseParallelGC -XX:ParallelGCThreads=2 -XX:+UseParallelOldGC -XX:MaxGCPauseMillis=200 -XX:+UseAdaptiveSizePolicy -XX:+PrintClassHistogram -XX:+PrintGCDetails -Xloggc:/data/tgbc/gclogs/${jar_service}/gc.$$.log -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -jar admin-1.0-SNAPSHOT.jar –spring.profiles.active=pro
tcpdump使用
GET : tcpdump -A -s 0 ‘tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) – ((tcp[12]&0xf0)>>2)) != 0)’
POST: tcpdump -X -s 0 ‘tcp port 80 and (((ip[2:2] – ((ip[0]&0xf)<<2)) – ((tcp[12]&0xf0)>>2)) != 0)’
task执行一段时间停掉了
1. spring schedule线程池默认大小为1;
2. RestTemplate默认使用HttpClient,他的默认连接超时时间:-1,默认读取超时时间:-1; 调用接口时,读取阻塞,从而导致task不可用;
前后端分离,无法登陆获取jsessionid
前后端分离调登录接口的一个问题,调用(POST)登录接口不会创建jsessionid,导致后面的接口拿不到用户信息,只有先调用任何一个GET请求,先生成jsessionid,再去掉登录接口,才能保证后续接口正常调用
解决:设置server.session.cookie 的 httpOnly=false, secure=false,这样post请求就能生成 JSessionid
lombok 生成构造函数时,加上变量的注解
场景:比如我想把 @Qualifier 加到 lombok @RequiredArgsConstructor 注解自动生成的构造函数的参数上,怎么破?
# Copy the Qualifier annotation from the instance variables to the constructor
# see https://github.com/rzwitserloot/lombok/issues/745
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
这是最近在lombok 1.18.4中引入的;
不这样做的话,可能会遇到:Parameter 1 of constructor in xxx.WeWorkController required a single bean, but 2 were found;
效果:
/////////////////////////////////////////////////////////////////////////////////////////////////
////// WeWorkController.java
/////////////////////////////////////////////////////////////////////////////////////////////////
@RequiredArgsConstructor
public class WeWorkController {
@Qualifier("wxCpZService")
final WxCpService zService;
@Resource(name = "wxCpOAService")
final WxCpOAService wxCpOAService;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
////// WeWorkController.class
/////////////////////////////////////////////////////////////////////////////////////////////////
public WeWorkController(@Qualifier("wxCpZService") final WxCpService zService, final WxCpOAService wxCpOAService) {
this.zService = zService;
this.wxCpOAService = wxCpOAService;
}
@MockBean 引发的 NoUniqueBeanDefinitionException
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.xxx.goods.infrastructure.dao.mapper.PrdGoodsMapper’ available: expected single matching bean but found 2: prdGoodsMapper,com.digibms.goods.infrastructure.dao.mapper.PrdGoodsMapper#0
问题描述:@MockBean 导致出现重复的bean:com.digibms.goods.infrastructure.dao.mapper.PrdGoodsMapper#0,实际的bean:prdGoodsMapper
解决方法:
@MockBean(name = "prdGoodsMapper") // name 和 实际的bean的name一致即可
see:https://github.com/spring-projects/spring-boot/issues/6541#issuecomment-238524659
WebMvcConfigurationSupport 导致 json 转换失效
问题:项目中自定义了 WebMvcConfigurationSupport,用来添加自己的拦截器,但 WebMvcConfigurationSupport 这个类里面实现了默认的 HttpMessageConverter,
导致我在其他地方配置的 ObjectMapper、application.yml(spring.jackson.date-format: yyyy-MM-dd HH:mm:ss) 均没有生效)
思路:我们去看 org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#messageConverters 中的 MappingJackson2HttpMessageConverter 是从哪里生成的,
它的 org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#objectMapper 是从哪里注入的
解决:
- 依靠 spring 进行解决
- 使用 WebMvcConfigurer 代替 WebMvcConfigurationSupport,同时使用下面的代码注册 ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
springboot不允许请求参数带特殊字符,如:{},会报400错误
其实是服务器(tomcat、undertow)不支持,需要单独配置
tomcat
TODO
undertow
@Component
public class MyWebServerCustomizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
@Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ALLOW_UNESCAPED_CHARACTERS_IN_URL, Boolean.TRUE));
}
}
参考:https://juejin.cn/post/6844903913142009863