JoyLau's Blog

JoyLau 的技术学习与思考

Windows下最适合编程的字体要数Consolas字体了,那么如何将命令提示符换成Consolas字体呢?我们只需要注册以下信息即可:

1
2
3
4
5
6
7
8
9
10
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe]
"WindowSize"=dword:00170058
"ScreenBufferSize"=dword:01170058
"WindowPosition"=dword:0079004b
"ColorTable01"=dword:00235600
"FontSize"=dword:00120000
"FontWeight"=dword:00000190
"FaceName"="Consolas"
"FontFamily"=dword:00000036

新建一个文本文件,将信息保存到此文本文件中
然后将文本文件重命名为*.reg
双击此文件将其注册

通常的属性注入

一般情况下我们使用Spring或者SpringMVC的时候会使用@Value()注入

使用SpringBoot的时候会使用@ConfigurationProperties(prefix = "xxxx")

注入自定义的呢?这样:@ConfigurationProperties(prefix = "xxx",locations = "classpath:config/xxxx.properties")

更复杂一点的注入

如上图所示我注入了一个List<String>

拓展

那么同样的方式,是否可以注入Map,String[]….呢?

思考

properties的文件被读取的时候使用的就是Map,那么我们知道Map是无序了,这样就会导致我们原先要求的一致性可能达不到

解决方式

properties文件改成采用yml文件,或者升级SpringBoot的版本,貌似新版本采用的LinkedHashMap

引用本地包并打包部署的问题

背景

  • 在最近的开发中需要对接C++服务提供的ZeroC Ice接口,客户机环境安装了和服务环境相同的Ice,服务端的Ice比较老,是3.4.0的版本
    在maven的中央仓库中没有找到ice-3.4.0的jar包,只能引用安装路径下提供的jar了

那么常用的写法是这样的:(包括但不限于SpringBoot)

1
2
3
4
5
6
7
8
<!--Ice-->
<dependency>
<groupId>Ice</groupId>
<artifactId>Ice</artifactId>
<version>3.4.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/lib/Ice.jar</systemPath>
</dependency>

我是在src下新建的lib目录,在开发编译的是没有问题的。

在进行打包的时候发现Ice.jar没有被打进去

相对于这个应用来说,打成jar包是最合适的做法了

这里说一下,用package打包,不要用SpringBoot插件的jar打包

解决

build里加上这一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
..............
<resources>
<resource>
<directory>src/lib</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>BOOT-INF/classes/</targetPath>
</resource>
</resources>
</build>

之后,再打包,再解压一看,果然是打进去了,完美~

然后,遇到了新问题……..

以jar运行时没有主清单属性

之后便很愉快的使用 java -jar xxxxx.jar

提示:没有主清单属性

再解压一看,有Application.java类,但是jar包的大小明显不对,光SpringBoot父项目依赖的jar至少也有10+M了,这个大小明显不对

在结合没有主属性的错误,知道了错误的原因在这:

1
2
3
4
5
6
7
8
9
10
11
   <dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependencyManagement>

我用的项目是多模块依赖

解决的方式是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-dependencies.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</build>

正如我文章截图的那样,解决问题!

父项目依赖,打包成jar

同时加入以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

2017年9月19日更新

SpringBoot 项目打包时修改 MANIFEST.MF 文件

一般情况下我们的 MANIFEST.MF内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Manifest-Version: 1.0
Implementation-Title: joylau-media
Implementation-Version: 1.7-RELEASE
Archiver-Version: Plexus Archiver
Built-By: JoyLau
Implementation-Vendor-Id: cn.joylau.code
Spring-Boot-Version: 1.5.4.RELEASE
Implementation-Vendor: Pivotal Software, Inc.
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: cn.joylau.code.JoylauMediaApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_45
Implementation-URL: http://projects.spring.io/spring-boot/joylau-media
/

解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork : 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->
<fork>true</fork>
</configuration>
</plugin>

//修改版本号,一般为pom文件的版本
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestEntries>
<Manifest-Version>${version}</Manifest-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>

SpringBoot 项目中引入缓存

  • 引入依赖
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

@EnableCaching 开启缓存

@CacheConfig(cacheNames = “api_cache”) 配置一个缓存类的公共信息

@Cacheable() 注解到方法上开启缓存

@CachePut() 根据使用的条件来执行具体的方法

@CacheEvict() 根据配置的参数删除缓存

SpringBoot默认支持很多缓存,spring.cache.type就可以知道,默认的是实现的是SimpleCacheManage,这里我记一下怎么设置缓存的超时时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
@EnableCaching
@EnableScheduling
public class CachingConfig {
public static final String CACHENAME = "api_cache";
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager(CACHENAME);
}
@CacheEvict(allEntries = true, value = {CACHENAME})
@Scheduled(fixedDelay = 120 * 1000 , initialDelay = 500)
public void reportCacheEvict() {
System.out.println("Flush Cache " + dateFormat.format(new Date()));
}
}

这里巧妙的使用了 定时任务,再其加上注解CacheEvict来清除所有cache name 为 api——cache 的缓存,超时时间是120s

在说说我比较喜欢的使用方式

单独写了篇文章,戳下面:

持续更新中…

问题

  • 用jackson 作为json转换器的时候,如果传入的json的key 比接收对象多的话,就会报错

解决

先看下SpringMVC原来的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>

这里的json转换器配置的是:org.springframework.http.converter.json.MappingJackson2HttpMessageConverter

我们进入到这个类中发现,这个类是继承的 AbstractJackson2HttpMessageConverter

AbstractJackson2HttpMessageConverter 继承的是 AbstractHttpMessageConverter<Object>
找到这个包下面 有一个类 GsonHttpMessageConverter 同样继承的 AbstractHttpMessageConverter<Object>
OK,就是他了

1
2
3
4
5
6
7
8
9
10
11
12
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.GsonHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>

这样,参数就随便你整吧,多点少点杜无所谓,完全匹配不上就返回个{}给你

来看下fastjson

fastjson下面有这个一个 package : com.alibaba.fastjson.support.spring

根据字面意思可知,这里是对spring的支持

找到下面这个class FastJsonHttpMessageConverter

1
public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object>

OK,这个类同样也是继承了 AbstractHttpMessageConverter

只要把这个类注入进去就可以了

SpringBoot使用FastJSON解析数据

  • 第一种继承WebMvcConfigurerAdapter,重写configureMessageConverters方法:
1
2
3
4
5
6
7
8
9
10
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
FastJsonHttpMessageConverter converter=new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig= new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
converter.setFastJsonConfig(fastJsonConfig);
converters.add(converter);

}
  • 第二种方式bean注入HttpMessageConverters:
1
2
3
4
5
6
7
8
9
@Bean  
public HttpMessageConverters fastJsonHttpMessageConverters() {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastConverter;
return new HttpMessageConverters(converter);
}

2017年普通高等学校招生全国统一考试

程序员的高考试卷(A卷) `考生类别:码农`

1、程序员A:借我1000元吧。程序员B:给你凑个整数。程序员B借给程序员A多少钱?()

   A. 1000元
   B. 1024元
   C. 1111元

2、程序员A:嘿 //是什么意思啊?程序员B:嘿.程序员A:呃 我问你//是什么意思?程序员B:问吧.程序员A:我刚才不是问了么?程序员B:啊?程序员A到底问了程序员B什么问题?()

   A. 嘿
   B. 呃 我问你
   C. //是什么意思

3、为什么程序员分不清万圣节和圣诞节?()

   A. 因为 31 OCT == 25 DEC
   B. 程序员只有加班/不加班,不过节
   C. 程序员没有女朋友,不过节

4、程序员最怕弹出的窗口是()

   A.   选项A

   B.   选项B

   C.   选项C

5、程序员:哎,太累了日子没法过了,怎么才能换行啊?()

   A. 打回车
   B. 不换行,日子不过了
   C. 除了敲代码,都不会,换行还是敲代码啊

6、程序员会给自己的孩子起什么名字?()

   A. 依依、灵灵、依灵、灵依、依初
   B. Ctrl、Alt 、Delete
   C. 程序员怎么会有女朋友?

7、如何快速挣到一百万?()

   A. while
   B. 买彩票
   C. 当乞丐

8、程序员下班前给老婆打电话:老婆,晚饭我带回来吃,你说买些啥?老婆:买1斤包子吧,如果遇到卖西瓜的,就买一个。程序员买包子时,看到旁边有人在卖西瓜。那么,程序员带了什么晚饭回家?()

   A. 1斤包子
   B. 1个包子
   C. 1个西瓜

9、我GET不到你的笑点,怎么办?()

   A. 智商不在一条线
   B. 太矮了,踩凳子上
   C. 用Post试试

10、为什么吸烟的程序员不在乎香烟盒上的那个警告?()

   A. 字太小
   B. 程序员眼中只有程序
   C. 不关心Warning,只关心Error

11、一对程序员恋人面对面坐着,他们在做什么?()

   A. 面向对象编程
   B. 喝咖啡
   C. 抱怨产品经理

12、老板:小程,下班前新版本一定要上线!小程:好的。第二天,老板上班,问小程:新版本怎么还没上线? 小程怎么回答的?()

   A. 版本出问题了
   B. 版本上线前需求又改了
   C. 我还没下班呢

![Title](//s3.joylau.cn:9000/blog/gaokao-title.jpg)

2017年普通高等学校招生全国统一考试

程序员的高考试卷(B卷) `考生类别:码神`

1、以下哪个概念和公孙龙的《指物论》中的“指”字含义相近?()

   A. 变量
   B. 数组
   C. 对象
   D. 指针

2、蔺相如,司马相如;魏无忌,长孙无忌。下列哪一组对应关系与此类似( )

   A. PHP,Python
   B. JSP,servlet
   C. java,java script
   D. C,C++

3、秦始皇吞并六国采用了以下哪种算法思想?( )

   A. 递归
   B. 分治
   C. 迭代
   D. 模拟

4、雅典王子忒修斯勇闯克里特岛斩杀米诺牛的时候采用了以下哪种算法?( )

   A. 动态规划
   B. 穷举
   C. 记忆化搜索
   D. Dijkstra算法

5、众里寻他千百度,蓦然回首,那人却在灯火阑珊处(辛弃疾《青玉案》)。所体现的算法是:( )

   A. 贪心
   B. 回溯
   C. 穷举
   D. 分治

6、《公孙龙子》记载:“齐王之谓尹文曰:‘寡人甚好士,以齐国无士,何也?’尹文曰:‘愿闻大王之所谓士者。’齐王无以应。”这说明了齐王:( )

   A. 昏庸无道
   B. 是个结巴
   C. 不会下定义
   D. 不会定义自己的需求

7、惠施曾提出过“卵有毛”的命题,以下哪一项是导致这个错误命题的原因:( )

   A. 混淆了命名空间
   B. 引入了错误的包
   C. 衍生类未重载
   D. 调用了危险的指针

8、下面哪种面向对象的方法可以让你变得富有?( )

   A. 继承
   B. 封装
   C. 多态
   D. 抽象

那么你能答对几题呢? 下期发布标准答案 滑稽

先来一张集合的

java-skill-tree1

Java核心技术总结

java-skill-tree2

J2EE技术总结

java-skill-tree3

工作学习总结

java-skill-tree4

大数据相关技术总结

java-skill-tree5

来看看Java工程师技能表

java-skill-tree6
java-skill-tree8
java-skill-tree9

恐怖的Linux大法

java-skill-tree7

Im Back

今天被问了一道题,是这样的:

求解:一筐鸡蛋:
1个1个拿,正好拿完
2个2个拿,还剩1个
3个3个拿,正好拿完
4个4个拿,还剩1个
5个5个拿,还差1个
6个6个拿,还剩3个
7个7个拿,正好拿完
8个8个拿,还剩1个
9个9个拿,正好拿完
问筐里最少有多少鸡蛋

能算出这道题的智商不一般!求答案?有高手没,算算吧!

”5个5个拿,是还差1个“,也就是还剩下4个,这是这个题目的一个小陷阱…

我第一反应想到的是这个数一定是63的倍数,但是后来就没有什么想法了。

再后来,我想到了一个残暴的方法,穷举法

1
2
3
4
5
6
7
8
9
10
int i = 1;
while (true) {
System.out.println(i);
if (i % 2 == 1 && i % 3 == 0 && i % 4 == 1 && i % 5 == 4 && i % 6 == 3 && i % 7 == 0
&& i % 8 == 1 && i % 9 == 0) {
System.out.println("鸡蛋数=" + i);
break;
}
i++;
}

执行后正确答案是1449;

能被7整除,能被9整除,所以肯定是63的倍数
如果利用63的倍数来做写的话:

1
2
3
4
5
6
7
8
9
int i = 1;
while (true) {
int num = 63 *i;
if (num%5==4&&num%6==3&&num%8==1) {
System.out.println("鸡蛋数=" + num);
break;
}
i++;
}

答案依旧是1449,稍微显得动了点头脑,但还是穷举法,有什么高大上的解法么???在下默默献上膝盖!

IntelliJIDEA-Plugins

说明

我现在用的这个插件时ECTranslation,是用于做中英文翻译的,可以在看文档和注释的是方便的使用,然而近期变得不好用了

  • 翻译的内容有时能出来,有时出不来,有时甚至没有反应
  • 查看了该款插件的源代码,发现是调用的有道翻译的API接口,而且在代码里写死了APIkey和KeyFrom
  • 调用了有道的API,加上上面作者提供的Key,再传入翻译的文本内容,发现返回值居然是请求次数过多,被封禁了…..
  • 明白了,很多使用这个插件的开发者都是用的作者提供的默认Key,默认情况下1小时请求的限制次数是1000次
  • 肯定是次数超了
  • 但是他的配置信息是写在代码里的,能配置到IDEA的面板上供使用者自己配置就好了
  • 于是我有了自己动手的想法

开始项目

第一步创建IDEA插件项目:
IntelliJIDEA-Build
第二步目录结构如下图所示:
IntelliJIDEA-Folder

项目配置

plugin.xml

看代码,相信能看懂的:

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
33
34
35
36
37
38
39
40
41
42
43
<idea-plugin>
<id>cn.joylau.plugins.translation</id>
<name>joylau-translation</name>
<version>1.0</version>
<vendor email="2587038142.liu@gmail" url="http://www.joylau.cn">JoyLau</vendor>

<description><![CDATA[
Plugin for translate English to Chinese.<br>
<li>1. Choose the word you want translate.</li>
<li>2. Press Ctrl + NUMPAD0.</li>
<li>3. Fork ECTranslation Change ApiKey and KeyFrom</li>

]]></description>

<change-notes><![CDATA[
<li>Change ApiKey and KeyFrom for myself</li>
<li>Change KeyMap to Ctrl + NumPad 0</li>
]]>
</change-notes>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="141.0"/>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<!-- uncomment to enable plugin in all products
<depends>com.intellij.modules.lang</depends>
-->

<extensions defaultExtensionNs="com.intellij">
<!-- Add your extensions here -->
</extensions>

<actions>
<!-- Add your actions here -->
<action id="ECTranslation" class="cn.joylau.plugins.translation.ECTranslation" text="Translate">
<add-to-group group-id="EditMenu" anchor="first"/>
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
<keyboard-shortcut keymap="$default" first-keystroke="ctrl NUMPAD0"/>
</action>
</actions>

</idea-plugin>

只有一个action ,调用的类是ECTranslation,快捷键设置的ctrl + NumPad 0

最后

代码都是人家的,我就没好意思往IDEA的仓库里上传了…

如果你想使用这个插件: 点击查看点击下载

更新(2023-08-02)

最近发现有道 API 的接口不能用了,无法返回翻译数据,于是重新修改了下插件,发布最新版本

地址: https://github.com/JoyLau/joylau-translation/releases/tag/V2

目前有个问题就是,现在的有道 API 是收费的,刚开始注册送 50 元,不过很快会用完的, 到时再换其他的翻译 API 吧

0%