1. jvisualvm
2. JConsole
3. jmc
以上三个都是jdk8自带的图形化JVM监测工具,我觉得最好用的是jmc,直接可以看到堆中的各个代内存占用,很直观。jmc牛逼就完事了
4. HotSpot中PS Scavenge
用于新生代的垃圾回收,主要处理新创建的对象和短期存活的对象。通常采用复制算法(Copying Algorithm),将存活的对象复制到另一个部分(例如Survivor区),然后清理未复制的对象。
在新生代进行垃圾收集时,会触发一次Minor GC(小型GC)
5. HotSpot中PS MarkSweep
PS MarkSweep用于老年代的垃圾回收,主要处理长期存活的对象和整理内存碎片。在PS MarkSweep过程中,通常采用标记-清除算法(Mark-Sweep Algorithm),先标记所有活动对象,然后清理未标记的对象,并可能会进行内存碎片整理。
在老年代需要进行垃圾收集时,可能会触发一次Full GC(完全GC)
6. poi模式
测试jvm参数过程中发现项目读取excel会oom
在POI库中,有两种主要的处理模式:用户模式和SAX模式。
- 用户模式(User API):
- 特点:也称为事件模型,这是POI库最常用的模式。在用户模式中,整个文档被读入内存并表示为一个对象模型(object model),这些对象对应于文档中的各个部分(如单元格、行、列等)。
- 适用场景:适合于需要在文档中进行复杂操作,如修改、创建新的内容,或者需要多次访问文档中的不同部分的情况。
- SAX模式:
- 特点:基于事件驱动的模型,与用户模式不同,SAX模式并不需要将整个文档加载到内存中。相反,它通过事件处理器(event handlers)在解析文档时产生事件(例如读取到一个单元格或一行数据),并允许开发者在每个事件发生时做出相应的响应。
- 适用场景:适合于处理大型文档或者需要一次性读取文档并且不需要在内存中保留文档数据的情况。SAX模式更加轻量级,能够在内存使用方面有所节省。
选择使用哪种模式:
- 如果你需要对文档进行复杂的修改或者多次访问文档中的不同部分,通常推荐使用用户模式(User API)。这种模式虽然会占用较多的内存,但是提供了更灵活、方便的操作方式。
- 如果处理的是大型文档或者只需一次性地读取文档内容并进行简单处理,那么SAX模式可能更为合适。它能够在处理效率和内存消耗之间取得平衡。
7. Code Cache
从字面意思理解就是代码缓存区,它缓存的是JIT(Just in Time)编译器编译的代码,简言之codeCache是存放JIT生成的机器码(native code)。当然JNI(Java本地接口)的机器码也放在codeCache里,不过JIT编译生成的native code占主要部分。
8. Compressed Class Space
压缩类空间实际上是用于存储类加载器和其加载的类信息,优化存储已加载类的信息而引入的,可以减少jvm内存占用。
9. ffmpeg amr转mp3
微信语音是amr格式的,无法播放,借助这个工具可以转换为mp3
10. /oauth/token
/oauth/token 是 Spring Security OAuth2 中的一个重要端点,用于获取访问令牌(Access Token)。这是 OAuth2 授权框架的一部分,用于为客户端提供访问资源服务器的令牌。
请求方法
通常,/oauth/token 端点使用 POST 方法。请求应包括以下参数:
- grant_type:授权类型,表示客户端如何获取令牌。常见的授权类型包括:
- authorization_code: 使用授权码获取令牌。
- password: 使用用户名和密码获取令牌。
- client_credentials: 使用客户端凭据获取令牌。
- refresh_token: 使用刷新令牌获取新的访问令牌。
- client_id和 client_secret:客户端的标识和密钥,用于验证客户端的身份。
- scope:请求的权限范围,表示客户端请求访问的资源范围。
- redirect_uri:用于 authorization_code 授权类型,指示用户授权后的重定向URI。
- code:授权码,用于 authorization_code 授权类型。
- username和 password:用于 password 授权类型,表示用户的凭据。
响应
成功的请求将返回一个 JSON 对象,其中包含访问令牌、令牌类型、到期时间和可能的刷新令牌。例如:
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "bearer",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}
11. jwt token为什么要在前面添加Bearer这个单词
协议规定就是这样,标准是Authorization: ,Bearer其实就是指的认证方式。
12. 检测nacos是否启动
做了个项目启动前更新nacos的代码,由于是脚本启动各个服务,结果我这个服务启动前,nacos还没起来,导致我更新nacos配置失败,所以执行前判断nacos是否已经启动,启动再更新nacos。
import com.alibaba.nacos.api.naming.NamingFactory; import com.alibaba.nacos.api.naming.NamingService; import com.alibaba.nacos.api.exception.NacosException; public class NacosHealthCheck { public static void main(String[] args) throws NacosException { String serverAddr = "localhost:8848"; // Nacos 服务器地址 // 创建 NamingService 实例 NamingService namingService = NamingFactory.createNamingService(serverAddr); // 调用健康检查 API String isNacosUp = namingService.getServerStatus(); if (StringUtils.equals("UP", isNacosUp))) { System.out.println("Nacos 服务已启动并运行正常"); } else { System.out.println("Nacos 服务未启动或运行异常"); } } }
13. HashMap putIfAbsent(key,value) 方法
以前一直以为只有当key不存在,才会将key、value插入map。
刚知道,即使key存在,如果value是null,也可以把key,value插入进去。
14. 零宽字符
一种看不见的字符,有好几种,随便取两种来,表示0和1,即可隐藏一些字符。例如密码,可以写个文档专门放关键密码。
15. ES范围查询QueryBuilders.rangeQuery()
在Elasticsearch中,如果你使用 QueryBuilders.rangeQuery() 来构建一个范围查询,比如 gte(大于等于)和 lte(小于等于),要注意的是这些查询通常是基于数值比较而非精确的日期时间戳。因此,在处理日期时,如果你的字段存储的是精确到毫秒的时间戳(比如UNIX时间戳),会涉及到时区和精度的问题。
16. gc overhead limit exceeded
当前已经没有可用内存,经过多次GC 之后仍然没能有效释放内存
17. spring Date es @Query
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"bool\" : {\"must\" : {\"match\" : {\"title\" : \"?0\"}}}}")
List<Book> findByTitleUsingCustomQuery(String title);
}
18. es text和keyword查询
text类型
{
"query": {
"match": {
"your_text_field": "your_search_query"
}
}
}
如果你的字段是
keyword类型,你应该使用
term查询而不是
match查询来执行精确匹配
{
"query": {
"term": {
"your_keyword_field": "exact_value_to_match"
}
}
}
19. es查询报错bool query does not support term
这是由于在布尔查询中不能直接使用term查询子句。
布尔查询(bool query)在Elasticsearch中用于组合多个查询子句,例如must、should、filter和must_not等。
布尔查询(bool query)的结构
布尔查询允许你以逻辑方式组合不同的查询条件。它有以下几种子句:
- must: 必须匹配的查询条件,相当于逻辑与(AND)。
- should: 应该匹配的查询条件,相当于逻辑或(OR)。
- filter: 过滤查询条件,它不会像must那样影响评分,通常用于精确匹配或范围查询。
- must_not: 必须不匹配的查询条件,相当于逻辑非(NOT)。
解决方法
如果你想在布尔查询中执行精确匹配,应该使用term查询作为bool查询中的filter子句。这是因为filter不计算评分,适用于精确匹配或范围查询,而term查询正是用于精确匹配的。例如:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" }}
],
"filter": [
{ "term": { "category": "Programming" }}
]
}
}
}
在这个例子中:
- must子句指定了一个match查询,要求title字段包含"Elasticsearch"。这会影响文档的相关性评分。
- filter子句指定了一个term查询,要求category字段精确匹配"Programming"。
20. 达梦select count(*) as count
结果会把列名改为COUNT而不是count,达梦去死
21. 使用stream报错java.lang.IllegalStateException: Duplicate key
如果有key冲突需要自己处理,(entity1, entity2) -> entity1也就是说当出现了重复key的数据时,会回调这个方法,处理重复数据,这里是有重复则不再进行插入操作。
List<Users> list = new ArrayList<>();
Map<String, Integer> usersMap=list.stream().collect(
Collectors.toMap(
Users::getNames,
Users::getAges,
(entity1, entity2) -> entity1
)
);
22. Java泛型?和T
通配符和占位符
-
?:在泛型中,问号 ? 表示通配符(Wildcard)。它通常用于泛型类型中,表示任意类型。通配符有几种形式:
-
? extends T:表示通配符所代表的类型是 T 或 T 的子类。
-
? super T:表示通配符所代表的类型是 T 或 T 的父类。
-
?:表示未知类型,即任意类型。
-
T:在泛型中,T 是一种类型参数的占位符。它表示任意类型,可以是类类型(例如 String、Integer 等)、接口类型或者通配符类型。在定义泛型类、接口或方法时,T 被用作类型参数,使得代码可以处理多种类型而不需要重复编写类似的代码。例如,在一个泛型类 Box 中,T 可以被任何类替换,使得 Box 类可以存储和返回任意类型的对象。
23. mybatis select by example
mybatis codehelper带的功能,可以此类查询,感觉类似于mybatisplus那种,可以不写sql查数据。
24. mybatis-plus id生成
实现idGenerator,然后重写方法,最后把生成的类注入进我们的项目即可。
25. idea热部署原理 GPT
Java代码之所以可以实现热部署(Hot Deployment),主要得益于Java虚拟机(JVM)的运行机制以及类加载器(ClassLoader)的设计。以下是其原理:
- 动态类加载机制:Java的类加载机制允许在程序运行时动态加载和卸载类。类加载器(ClassLoader)负责将类文件加载到内存,并生成对应的类对象。Java中的类加载器是一个层级结构,不同的类加载器负责加载不同位置的类文件(如本地文件系统、网络、数据库等),并且支持在运行时动态添加新的类加载器。
- 热部署原理: 当需要热部署时,新的类文件被放置到指定的位置(如文件系统的特定目录),然后通过自定义的类加载器(通常是自定义的子类加载器)加载这些类文件。由于类加载器的层级关系,如果一个类在父类加载器中没有找到,就会尝试在子类加载器中查找。因此,通过新建一个类加载器并加载更新后的类文件,就能够在不重启JVM的情况下更新程序的部分功能。
- 类加载器的隔离性:JVM中的类加载器之间是隔离的,同一个类在不同的类加载器实例中被加载后,会形成不同的类对象。这意味着,当更新了类文件并通过新的类加载器加载后,旧版本的类对象依然存在于内存中,而新版本的类对象则由新的类加载器生成,因此可以避免对现有代码的影响。
- 类的卸载:JVM具备垃圾回收机制,当一个类不再被引用时,该类及其实例将被回收。因此,当旧版本的类对象没有任何引用时,垃圾回收机制会将其释放,从而实现类的卸载。
总结来说,Java代码可以热部署的关键在于类加载器的动态加载机制和类加载器之间的隔离性,这使得我们可以在应用程序运行时动态地加载和替换类文件,实现代码的热更新而无需重启整个应用程序。
26. JVMTI(Java Virtual Machine Tool Interface) GPT
JVMTI是Java虚拟机工具接口,它是一组用于开发调试工具和监控工具的API。JVMTI允许开发人员访问和监视Java应用程序在JVM上运行时的内部状态和行为。
作用和功能:
- 调试:JVMTI允许开发人员编写调试器,可以在运行时检查和修改Java程序的状态,包括查看和修改变量、监视方法的调用、捕获异常等。调试器可以通过JVMTI接口与JVM进行通信,从而实现对Java程序的调试和诊断。
- 性能分析:JVMTI使得开发人员能够实时地监控Java应用程序的性能数据,如内存使用情况、线程运行状态、方法执行时间等。这对于性能优化和问题排查非常有帮助。
- 内存分析: JVMTI提供了一些接口,使得开发人员能够获取Java堆内存的详细信息,如对象的分布、对象的生命周期等,有助于进行内存泄漏检测和优化内存使用。
- 安全审计:JVMTI还可以用于实施安全策略和进行安全审计,监控Java应用程序的行为,防止恶意代码的执行或检测不当的访问行为。
- 代码检查和修改:通过JVMTI,可以检查和修改Java程序的字节码,这对于某些调试和分析工具非常重要。
使用场景:
- 开发调试工具:如Eclipse的调试器、VisualVM等工具,它们利用JVMTI接口与JVM交互,实现对Java程序的调试功能。
- 性能分析工具:如Java Mission Control(JMC)和VisualVM等工具,利用JVMTI接口监控和分析Java程序的性能特征。
- 内存分析工具:如Eclipse Memory Analyzer(MAT)等工具,利用JVMTI接口分析Java程序的内存使用情况和内存泄漏问题。