211231-Java调用本地程序的几种姿势

作为一个后端同学,经常被安全的小伙伴盯上,找一找安全漏洞;除了常说的注入之外,还有比较吓人的执行远程命令,唤醒本地应用程序等;然后有意思的问题就来了,写了这么多年的代码,好像还真没有尝试过用java来唤醒本地应用程序的

比如说一个最简单的,打开本地的计算器,应该怎么搞?

接下来本文将介绍一下如何使用java打开本地应用,以及打开mac系统中特殊一点的处理方式(直白来说就是不同操作系统,使用姿势不一样)

211228-Jar文件提取与查看

最近遇到一个奇怪的问题,一个jar包无法解压,直接使用jar xvf xxx.jar没有任何响应

因为实际想看的只是jar包中的某个class文件,基于此可以通过 jar tf 查看文件列表,在通过 jar xf xxx.jar xxxfile的方式来解压指定文件来实现目的

接下来记录一下jar包的几个操作case

211209-Java使用URI.create()注意事项

记录一个在实际使用过程中遇到的问题,在解析一个url格式的字符串中的域名时,直接使用下面这种姿势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static ImmutablePair</**host*/String, /**uri*/String> foramtUri(String uri) {
// uri中空格去除,避免转换异常
URI u = URI.create(uri);
String host = u.getHost();
if (u.getPort() > 0 && u.getPort() != 80) {
host = host + ":80";
}

String baseUri = u.getPath();
if (u.getFragment() != null) {
baseUri = baseUri + "#" + u.getFragment();
}

if (StringUtils.isNotBlank(baseUri)) {
baseUri = host + baseUri;
} else {
baseUri = host;
}

return ImmutablePair.of(host, baseUri);
}

正常使用上面这种进行解析,没啥问题,结果某天突然抛了个异常

211126-Java实现位图转矢量图

通过前面几篇图片转字符、灰度图的文章介绍之后,接下来我们再来看一个有意思的东西,基于前文的基础,实现位图转矢量图的功能

关于位图与矢量图的简单理解如下:

  • 位图:如Jpg/png,放大之后会失真,看到像素块
  • 矢量图:如svg,放大图片也不会失真

211122-Java实现GIF图转字符动图实例demo

上一篇文章介绍了静态图转字符的实现demo;接下来也该是动态图转字符的demo了

从前面几篇文章的学习过程中,要想实现这个功能就属于信手拈来了

211121-Java实现图片转字符输出示例demo

前面几篇博文介绍了使用jdk来对图片做一些有意思的转换,接下来我们再介绍一个有意思的玩法,直接根据图片,输出一个二维字符数组,实现用字符来实现绘画的场景

211120-Java实现Gif图转字符动图

前面介绍了两篇基于jdk实现图片灰度处理、转字符图片的操作,接下来我们在将之前的能力扩展一下,支持将一个gif图灰度化或者转gif字符图

211116-Java实现图片转字符图片示例demo

前面介绍了一篇java实现图片灰度化处理的小demo,接下来再介绍一个有意思的东西,将一个图片转换成字符图片

211112-Java实现图片灰度化

本文通过一个简单的实例,演示如何使用java来实现图片灰度化处理,主要借助下面两种策略来处理颜色

灰度化公式

1
avgColor = red * 0.299f + green * 0.587f + blue * 0.114f

均值方式

1
avgColor = (red + green + blue) / 3.0f

211108-封装一个根据路径获取文件资源的工具类

通常我们最多的场景是从本地资源中读取文件,这个时候我们经常需要注意的是相对路径、绝对路径问题;

除了从本地获取文件之外,从网络中获取文件资源(如图片)也属于相对常见的场景,接下来我们封装一个工具类,可以支持以上各种类型的数据读取

211011-构建一个创建Map的工具类来辅助理解可变传参

虽说java作为编译语言,但是它本身也提供了很多运行时能力,今天介绍一个非常基础的知识点,可变参数传递

210518-String#format数量不匹配抛异常

偶然发现一个问题,在使用String.format进行格式化输出时,发现参数个数不匹配时,会抛出异常,如

1
String msg = String.format("hello %s, %s", "a");

上面这个执行之后,会抛MissingFormatArgumentException异常,提示信息如

1
java.util.MissingFormatArgumentException: Format specifier '%s'

210412-JDK 常见并发控制手段

单实例的并发控制,主要是针对JVM内,我们常规的手段即可满足需求,常见的手段大概有下面这些

  • 同步代码块
  • CAS自旋
  • 阻塞队列,令牌桶等

210225-分页遍历的两种使用姿势

在日常开发中,分页遍历迭代的场景可以说非常普遍了,比如扫表,每次捞100条数据,然后遍历这100条数据,依次执行某个业务逻辑;这100条执行完毕之后,再加载下一百条数据,直到扫描完毕

那么要实现上面这种分页迭代遍历的场景,我们可以怎么做呢

本文将介绍两种使用姿势

  • 常规的使用方法
  • 借助Iterator的使用姿势

210129-Java对象内存地址输出

当一个对象没有重写hascode方法时,它返回的内存地址,当覆盖之后,我们有什么办法获取对象的内存地址么?

  • 使用 System.identityHashCode() 输出内存地址

210121-StringUtils字符串分割使用姿势异常记录

字符串分割,属于比较常见的case了,在实际开发中,相信很多小伙伴会借助common-lang工具包中的StringUtils来实现,使用姿势也很简单

1
String[] ans = StringUtils.split("a,b,c", ",");

一般来讲上面这种使用方式没有问题,但是当分隔符前后为空时,需要特别注意,可能会和你预期的返回不一致

210107-Spring工具类之基本元素判断

实际业务开发中偶尔会遇到判断一个对象是否为基本数据类型,除了我们自老老实实的自己写之外,也可以借助Spring的 BeanUtils 工具类来实现

1
2
3
4
5
// Java基本数据类型及包装类型判断
org.springframework.util.ClassUtils#isPrimitiveOrWrapper

// 扩展的基本类型判断
org.springframework.beans.BeanUtils#isSimpleProperty

201021-LRU算法急速实现版

借助LinkedHashMap飞速实现一个LRU算法的缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.LinkedHashMap;
import java.util.Map;

/**
* 基于LinkedHashMap实现的LRU算法
* Created by @author yihui in 17:36 20/10/19.
*/
public class LruCache<K, V> extends LinkedHashMap<K, V> {
private int size;

public LruCache(int size) {
super(size, 0.75f, true);
this.size = size;
}

@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
// 当元素个数,超过指定的大小时,淘汰最老的数据
return size() > size;

}

public static void main(String[] args) {
LruCache<String, Integer> cache = new LruCache<>(4);
for (int i = 0; i < 6; i++) {
cache.put("key_" + i, i);
System.out.println(cache);
}

System.out.println(cache.size);
}
}

200303-如何优雅的在java中统计代码块耗时

在我们的实际开发中,多多少少会遇到统计一段代码片段的耗时的情况,我们一般的写法如下

1
2
3
4
5
6
long start = System.currentTimeMillis();
try {
// .... 具体的代码段
} finally {
System.out.println("cost: " + (System.currentTimeMillis() - start));
}

上面的写法没有什么毛病,但是看起来就不太美观了,那么有没有什么更优雅的写法呢?

200111-老哥,你真的知道HashMap初始化大小如何设置么

HashMap对于javer而言,可以说是非常非常熟悉的一个容器类了,可以说99.99%的java开发者都用过它,那么你知道怎样创建一个HashMap是最优雅的方式呢?

190909-Java之输出异常堆栈信息

在代码出现异常时,堆栈信息可以有效的辅助定位和排除问题,异常堆栈一般是怎么打印的呢

190605-记录BigDecimal转int四舍五入的姿势

从db中查了一个BigDecimal数据,希望按照四舍五入的方式进行取整,发现直接使用 intValue 不太对,特此记录一下正确姿势

1
new BigDecimal(4.51).setScale(0, RoundingMode.HALF_EVEN).intValue()

190529-Java之HashMap迭代删除使用方法小结

map的迭代删除,和我们常见的list,set不太一样,不能直接获取Iteraotr对象,提供的删除方法也是单个的,根据key进行删除,如果我们有个需求,将map中满足某些条件的元素删除掉,要怎么做呢?

190521-JDK之List遍历删除的几种使用姿势

在实际的业务开发中,容器的遍历可以说是非常非常常见的场景了,遍历删除呢,用的机会也不会少,但你真的会用么

190515-老哥你真的知道ArrayList#sublist的正确用法么

我们有这么一个场景,给你一个列表,可以动态的新增,但是最终要求列表升序,要求长度小于20,可以怎么做?

这个还不简单,几行代码就可以了

1
2
3
4
5
6
7
8
public List<Integer> trimList(List<Integer> list, int add) {
list.add(add);
list.sort(null);
if (list.size() > 20) {
list = list.subList(0, 20);
}
return list;
}

180926-Java之数值型的字面值中使用下划线

之前偶然在一个开源项目中看到下面这种写法,深感惊奇,当时没有记录,后来果不其然就忘掉了这种写法,现在又看到这种写法,特此记录

1
long price = 1_000_123L;

180918-JDK之Deflater压缩与Inflater解压

JDK 压缩与解压工具类

在实际的应用场景中,特别是对外传输数据时,将原始数据压缩之后丢出去,可以说是非常常见的一个case了,平常倒是没有直接使用JDK原生的压缩工具类,使用Protosutff和Kryo的机会较多,正好在实际的工作场景中遇到了,现在简单的看下使用姿势

180911-获取应用中所有线程

如何获取应用中,所有活动的线程?

1
2
3
4
ThreadGroup group = Thread.currentThread().getThreadGroup();
// 激活的线程数加倍
int estimatedSize = group.activeCount() * 2;
Thread[] slackList = new Thread[estimatedSize];

上面是获取当前线程所在的ThreadGroup, 然后将这个分组内的所有线程丢到slackList数组中,实际测试时,数组大小可能是大于实际的线程数的(而且可能性特别大)

通过ThreadGroup,还可以获取上一层的Group, 然后遍历所有的线程

180827-Java获取类路劲的几种姿势小结

I. Java获取类路劲的几种姿势小结

在Java环境中,如何获取当前类的路径,如何获取项目根路径,可以说是比较常见的需求场景了,下面简单的记录一下

180706-BigDecimal除法的精度问题

BigDecimal除法的精度问题

在使用BigDecimal的除法时,遇到一个鬼畜的问题,本以为的精度计算,结果使用返回0,当然最终发现还是自己的使用姿势不对导致的,因此记录一下,避免后面重蹈覆辙

180615-精度计算BigDecimal

180615-精度计算BigDecimal

目前接触的业务中,对数据的精度要求比较高,因此不再使用基本的float,double,改为用BigDecimal进行存储和相关的计算,端午前的这一篇博文,则简单的介绍下BigDecimal的使用姿势,早点回家早点放假

180606-Linux下jdk中文乱码问题解决

linux下jdk中文乱码问题解决

之前遇到过一次中文乱码问题,是通过在jdk的jre目录下的lib/fonts文件中添加simsun.ttf字体文件解决,但是这次遇到一个奇怪的问题,同样的字体拷贝过去后,中文不乱但是英文乱码了

记录一下解决过程:

  • 主要思路就是给系统安装中文字体,让系统本身就支持中文即可

180530-通过反射获取泛型类的实际参数

反射获取泛型类的实际参数

泛型用得还是比较多的,那么如何获取泛型类上实际的参数类型呢?

ConcurrentHashMap之1.7与1.8小结

I. ConcurrentHashMap 两种实现方式小结

1. 锁分段机制

HashMap的底层数据结构是数组+hash链表的方式,非线程安全

ConcurrentHashMap 采用锁分段机制,底层数据结构为二维数组,其中第一层是Segment的数组,每个Segment持有一把独立的锁,而Segment的结构和HashMap很相似;这就是锁分段机制;线程安全

关注几个点:

  • ConcurrentHashMap 如何定位 Segment, 如何定位 HashEntry
  • 修改的加锁逻辑,如何进行扩容
  • 读数据时,如何做到不加锁但保证线程安全的?

基于ForkJoin构建一个简单易用的并发组件

基于ForkJoin构建一个简单易用的并发组件

在实际的业务开发中,需要用到并发编程的知识,实际使用线程池来异步执行任务的场景并不是特别多,而且一般真的遇到了需要并发使用的时候,可能更加常见的就是直接实现Runnable/Callable接口,丢到Thread中执行了;或者更高级一点,定义一个线程池,扔进去执行;本片博文,将从另一个角度,借助JDK提供的ForkJoin,来设计一个简单易用的并发框架

Java并发学习之线程池ThreadPoolExecutor的小结

Java并发学习之线程池ThreadPoolExecutor的小结

本篇博文将带着问题来回顾小结多线程池相关的知识点

  1. 线程池的几种创建方式
  2. 线程池的优点是什么
  3. 应用场景
  4. 如何使用
  5. 实现原理
  6. 异常状况怎么处理
  7. 线程池中任务的提交执行后,到线程执行,执行完成的整个流程逻辑
  8. 线程池中的线程回收机制

Java可以如何实现文件变动的监听

Java可以如何实现文件变动的监听

应用中使用logback作为日志输出组件的话,大部分会去配置 logback.xml 这个文件,而且生产环境下,直接去修改logback.xml文件中的日志级别,不用重启应用就可以生效

那么,这个功能是怎么实现的呢?

JDK学习之反射的使用姿势一览

反射的学习使用

日常的学习工作中,可能用到反射的地方不太多,但看看一些优秀框架的源码,会发现基本上都离不开反射的使用;因此本篇博文将专注下如何使用反射

本片博文布局如下:

  1. 反射是什么,有什么用,可以做什么
  2. 如何使用反射
  3. 实例:

    • 利用反射方式,获取一个类的所有成员变量的name及值
    • 通过反射方式,修改对象的私有成员变量
    • 会通过写一个BeanUtils实现对象的成员变量值拷贝来覆盖上面两个场景

Java学习之深拷贝浅拷贝及对象拷贝的两种方式

I. Java之Clone

0. 背景

对象拷贝,是一个非常基础的内容了,为什么会单独的把这个领出来讲解,主要是先前遇到了一个非常有意思的场景

有一个任务,需要解析类xml标记语言,然后生成document对象,之后将会有一系列针对document对象的操作

通过实际的测试,发现生成Document对象是比较耗时的一个操作,再加上这个任务场景中,需要解析的xml文档是固定的几个,那么一个可以优化的思路就是能不能缓存住创建后的Document对象,在实际使用的时候clone一份出来

ForkJoin 学习使用笔记

ForkJoin 学习使用笔记

Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×