JoyLau's Blog

JoyLau 的技术学习与思考

前言

第一天学习 Hadoop 看了不少资料和文档,在这里想总结一下这一天的所学

感受

以前一直以为 JavaWeb 和大数据这是2条路子,学了大数据之后就要放下 JavaWeb,就像在项目中使用 Struts2 和 SpringMVC,2者只能选一个使用,在看了一些资料之后,我发现我的认识错了,其实 JavaWeb 和大数据技术就像 SpringMVC 和Spring Boot
2者是并行不悖的。大数据技术囊括很多技术,JavaWeb只是其中的一部分,要学习大数据需要学习的技术还有很多。

总结

Hadoop是干什么的

一句话概括:适合大数据的分布式存储与计算平台

Hadoop的2个重要部分

  • HDFS : 分布式文件系统
  • MapReduce : 并行计算框架

HDFS

主从结构:

主节点: 只有一个 namedode

从节点: 多个 datanode

namenode:

负责接收用户请求

维护文件系统的目录结构

管理文件与 block 之间的关系,block 与 datanode 之间的关系

datanode:

存储文件

文件被分成若干 Block 存储在磁盘上

为保证数据安全,文件会被备份成多个副本

MapReduce

主从结构:

主节点: 只有一个 JobTracker

从节点: 有多个 TaskTracker

JobTracker:

接受用户提交的任务

把计算任务分配给 TaskTracker 执行

监控 TaskTracker 的执行情况

TaskTracker:

执行 JobTracker 分配的任务

开始使用

引入依赖

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>

这里需要注意的是:
SpringBoot 的版本和 elasticsearch 的版本问题,在springboot 1.3.5 版本之前支持elasticsearch2.0 以下的版本,springboot1.3.5之后的版本支持elasticsearch5.0以下的版本
net.java.dev.jna 这个依赖是因为启动后报类不存在,加个jna依赖加上后就好了

配置文件

1
2
3
4
5
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: localhost:9300

这里需要注意的是:
elasticsearch对外提供的api的端口的是9200,提供各个集群间和客户端通信的是9300
配置文件里 cluster-nodes 配置项如果不填写的话,springboot应用启动时会自动创建内部的 elasticsearch 客户端,你会发现即是本地没开 elasticsearch 服务也能跑起来
配置多个集群的话 cluster-nodes 就配置多条信息,用逗号隔开

在 SpringBoot 项目中使用

  • 主要的一个接口ElasticsearchRepository<T,ID>,第一个是要存储的实体类,第二个参数是 ID 类型
  • 还有个 ElasticsearchCrudRepository,顾名思义就是增删改查
  • 自定义一个接口实现上述接口
  • 定义实体类
  • 自定义实现类可直接注入使用
  • 默认的已经存在了增删改查的方法了,可以直接使用
  • 想要更多的功能可以在接口中实现更多的自定义

自定义一个 DAO :

1
2
public interface SongDao extends ElasticsearchRepository<Song,Integer> {
}

定义一个实体类 :

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
@Data
@NoArgsConstructor
@Document(indexName = "songdb",type = "song")
public class Song {
@Id
private int id;

private String name;

private String author;

private long time;

private String commentKeyId;

private String mp3URL;

/*歌曲封面地址*/
private String picURL;

/*歌曲描述*/
private String describe;

/*专辑*/
private String album;

/*歌词*/
private String lyric;

/*mvid*/
private int mvId;
}

注意:
@Document注解里面的几个属性,类比mysql的话是这样:
index –> DB
type –> Table
Document –> row
@Id注解加上后,在Elasticsearch里相应于该列就是主键了,在查询时就可以直接用主键查询,后面一篇会讲到。其实和mysql非常类似,基本就是一个数据库
indexName在上述注解中需要小写

使用的话 注入SongDAO ,之后就可以看到相应的方法了
使用起来就是如此简单,感觉使用起来很像MongoDB配置

有一些注解的配置

有时候使用起来会有一些问题

  • 在默认策略下, Java 实体类叫什么名字,生成后的表名就叫什么,但我们可能并不想这样
  • 同样的道理,有时属性名和字段也并不想一样的

注解解决这些问题

  • @Id : 标明表的 ID , 自带索引,无需维护
  • @Document : 解决第一个问题
  • @Field : 解决第二个问题,默认不加@Field 有一写默认配置,一旦添加了@Filed注解,所有的默认值都不再生效。此外,如果添加了@Filed注解,那么type字段必须指定

入门使用就写到这

本文转自 阮一峰- 开源许可证教程

开源许可证教程

作为一个开发者,如果你打算开源自己的代码,千万不要忘记,选择一种开源许可证(license)。

许多开发者对开源许可证了解很少,不清楚有哪些许可证,应该怎么选择。本文介绍开源许可证的基本知识,主要参考了 OpenSource.com (12)。

一、什么是开源许可证

开源许可证是一种法律许可。通过它,版权拥有人明确允许,用户可以免费地使用、修改、共享版权软件。

版权法默认禁止共享,也就是说,没有许可证的软件,就等同于保留版权,虽然开源了,用户只能看看源码,不能用,一用就会侵犯版权。所以软件开源的话,必须明确地授予用户开源许可证。

二、开源许可证的种类

目前,国际公认的开源许可证共有80多种。它们的共同特征是,都允许用户免费地使用、修改、共享源码,但是都有各自的使用条件。

如果一种开源许可证没有任何使用条件,连保留作者信息都不需要,那么就等同于放弃版权了。这时,软件可以直接声明进入“公共领域”(public domain)。

根据使用条件的不同,开源许可证分成两大类。

  • 宽松式(permissive)许可证
  • Copyleft 许可证

三、宽松式许可证

3.1 特点

宽松式许可证(permissive license)是最基本的类型,对用户几乎没有限制。用户可以修改代码后闭源。

它有三个基本特点。

(1)没有使用限制

用户可以使用代码,做任何想做的事情。

(2)没有担保

不保证代码质量,用户自担风险。

(3)披露要求(notice requirement)

用户必须披露原始作者。

3.2 常见许可证

常见的宽松式许可证有四种。它们都允许用户任意使用代码,区别在于要求用户遵守的条件不同。

(1)BSD(二条款版)

分发软件时,必须保留原始的许可证声明。

(2) BSD(三条款版)

分发软件时,必须保留原始的许可证声明。不得使用原始作者的名字为软件促销。

(3)MIT

分发软件时,必须保留原始的许可证声明,与 BSD(二条款版)基本一致。

(4)Apache 2

分发软件时,必须保留原始的许可证声明。凡是修改过的文件,必须向用户说明该文件修改过;没有修改过的文件,必须保持许可证不变。

四、Copyleft 许可证

4.1 Copyleft 的含义

Copyleft 是理查德·斯托曼发明的一个词,作为 Copyright (版权)的反义词。

Copyright 直译是“复制权”,这是版权制度的核心,意为不经许可,用户无权复制。作为反义词,Copyleft 的含义是不经许可,用户可以随意复制。

但是,它带有前提条件,比宽松式许可证的限制要多。

  • 如果分发二进制格式,必须提供源码
  • 修改后的源码,必须与修改前保持许可证一致
  • 不得在原始许可证以外,附加其他限制

上面三个条件的核心就是:修改后的 Copyleft 代码不得闭源。

4.2 常见许可证

常见的 Copyleft 许可证也有四种(对用户的限制从最强到最弱排序)。

(1)Affero GPL (AGPL)

如果云服务(即 SAAS)用到的代码是该许可证,那么云服务的代码也必须开源。

(2)GPL

如果项目包含了 GPL 许可证的代码,那么整个项目都必须使用 GPL 许可证。

(3)LGPL

如果项目采用动态链接调用该许可证的库,项目可以不用开源。

(4)Mozilla(MPL)

只要该许可证的代码在单独的文件中,新增的其他文件可以不用开源。

五、常见问题

本节回答一些开源许可证的常见问题。

5.1 什么叫分发(distribution)?

除了 Affero GPL (AGPL) ,其他许可证都规定只有在“分发”时,才需要遵守许可证。换言之,如果不“分发”,就不需要遵守。

简单说,分发就是指将版权作品从一个人转移到另一个人。这意味着,如果你是自己使用,不提供给他人,就没有分发。另外,这里的“人”也指“法人”,因此如果使用方是公司,且只在公司内部使用,也不需要遵守许可证。

云服务(SaaS)是否构成“分发”呢?答案是不构成。所以你使用开源软件提供云服务,不必提供源码。但是,Affero GPL (AGPL) 许可证除外,它规定云服务也必须提供源码。

5.2 开源软件的专利如何处理?

某些许可证(Apache 2 和 GPL v3)包含明确的条款,授予用户许可,使用软件所包含的所有专利。

另一些许可证(BSD、MIT 和 GPL v2)根本没提到专利。但是一般认为,它们默认给予用户专利许可,不构成侵犯专利。

总得来说,除非有明确的“保留专利”的条款,使用开源软件都不会构成侵犯专利。

5.3 什么是披露要求?

所有的开源许可证都带有“披露要求”(notice requirement),即要求软件的分发者必须向用户披露,软件里面有开源代码。

一般来说,你只要在软件里面提供完整的原始许可证文本,并且披露原始作者,就满足了“披露要求”。

5.4 GPL 病毒是真的吗?

GPL 许可证规定,只要你的项目包含了 GPL 代码,整个项目就都变成了 GPL。有人把这种传染性比喻成“GPL 病毒”。

很多公司希望避开这个条款,既使用 GPL 软件,又不把自己的专有代码开源。理论上,这是做不到的。因为 GPL 的设计目的,就是为了防止出现这种情况。

但是实际上,不遵守 GPL,最坏情况就是被起诉。如果你向法院表示无法履行 GPL 的条件,法官只会判决你停止使用 GPL 代码(法律上叫做“停止侵害”),而不会强制要求你将源码开源,因为《版权法》里面没有相应的规定。

怎么使用?

pom 中引入插件:

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
<plugin>
<groupId>cn.joylau.code</groupId>
<artifactId>joylau-compressor-plugins</artifactId>
<version>1.2.RELEASE</version>
<executions>
<execution>
<id>resource-compressor</id>
<phase>compile</phase>
<goals>
<goal>resource-compressor</goal>
</goals>
</execution>
</executions>
<configuration>
<cssConfigs>
<cssConfig>
<dir>/static/css</dir>
<include>*.css</include>
<exclude>*.min.css</exclude>
</cssConfig>
</cssConfigs>
<jsConfigs>
<jsConfig>
<dir>/static/js</dir>
<include>*.js</include>
<exclude>*.min.js</exclude>
<munge>true</munge>
</jsConfig>
</jsConfigs>
<htmlConfigs>
<htmlConfig>
<dir>/templates</dir>
<include>*.html</include>
<removeIntertagSpaces>true</removeIntertagSpaces>
<compressJavaScript>false</compressJavaScript>
<compressCss>true</compressCss>
</htmlConfig>
</htmlConfigs>
</configuration>
</plugin>

配置解释

  • phase : compile 表明该插件在 compile 时调用

  • goal : 固定为 resource-compressor 不需要改变

  • cssConfigs , 可配置多个 cssConfig

    • cssConfig
      • dir: css文件目录
      • include:包含的css文件,支持通配符
      • exclude:排除的css文件,支持通配符
  • jsConfigs , 可配置多个 jsConfig

    • jsConfig
      • dir: js文件目录
      • include:包含的js文件,支持通配符
      • exclude:排除的js文件,支持通配符
      • munge: 是否进行代码混淆,缺省值为 false
      • preserveAllSemiColons : 保留所有的分号,缺省值为 false
      • disableOptimizations : 禁用自带的所有优化措施,缺省值为 false
  • htmlConfigs , 可配置多个 htmlConfig

    • htmlConfig
      • dir: js文件目录
      • include:包含的js文件,支持通配符
      • exclude:排除的js文件,支持通配符
      • removeComments: 是否移除注释,缺省值为 true
      • removeIntertagSpaces : 是否移除标签之间的空格,缺省值为 false
      • compressJavaScript : 是否对html里的js代码进行压缩,缺省值为 false
      • compressCss : 是否对html里的css代码进行压缩,缺省值为 false

压缩信息

当看到以下图片所示的信息后,则压缩成功

joylau-compressor-plugins

例如 :[INFO] common.js(8.71KB==>4.58KB,47.39%)

表示 :common.js 源文件大小8.71KB,压缩后大小 4.58KB,压缩率47.39%

GitHub 地址

源码已开源,地址 : https://github.com/JoyLau/joylau-compressor-plugins

  • 今天在浏览网站时,http://ai.baidu.com/ ,看到一个CSS3的效果:将鼠标放到图片上,图片会稍稍方大一点,当时很好奇是怎么做的
  • 当即百度了一下,有人用js做的,有人用css做的,首先js做的肯定不够好,一看效果就是css3的效果
  • 于是自己查看了下 这块 div 的效果
  • 将压缩的css展开来
  • 原来是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 鼠标移上去各浏览器的延时效果
.solution-img {
height: 100%;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transition: -webkit-transform .2s;
transition: -webkit-transform .2s;
-moz-transition: transform .2s,-moz-transform .2s;
transition: transform .2s;
transition: transform .2s,-webkit-transform .2s,-moz-transform .2s
}

# 鼠标移上去各浏览器的放大倍数
.solution-item:hover .solution-img {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1)
}

将 Scala 依赖 scala-library 和插件 scala-maven-plugin 添加到 Maven 项目中

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
    <dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.11.7</version>
</dependency>



<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>

更新完上面的内容之后,你需要等待Maven下载完所有的依赖。

安装IDEA插件 Scala
现在可以在Java工程中使用Scala代码了
创建新的文件夹src/main/scala;
Scala Maven插件将会识别这些目录,并且编译其中的Scala文件:

1
2
3
4
5
6
object BooksProcessor {
def filterByAuthor(author: String)(implicit books: util.ArrayList[Book]) = {
books.filter(book => book.getAuthor == author)
}

}

今天没有图片

在做单系统的情况下,我还是比较喜欢使用Google 的 Guava 来做缓存的,结合 SpringBoot 使用非常简单 :

1
2
3
4
5
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

再配置 yml :

1
2
3
4
5
6
spirng:
cache:
type: guava
cache-names: api_cache
guava:
spec: maximumSize=300,expireAfterWrite=2m

上述配置了一个 缓存名为 api_cache 的缓存 ,最大数量为300,超时时间为2分钟

接下来,在类中使用注解 @CacheConfig(cacheNames = “api_cache”) 来配置整个类的配置
@Cacheable() 注解在方法上来 开启方法的注解

使用很透明

今天再次使用时发现guava.spec提示过期了,查了下文档,文档原话是这样说的:

@Deprecated
@DeprecatedConfigurationProperty(
reason = “Caffeine will supersede the Guava support in Spring Boot 2.0”,
replacement = “spring.cache.caffeine.spec”
)

原来,在SpringBoot2.0中推荐使用Caffeine,表达式就是spring.cache.caffeine.spec

更改的方法很简单,改下依赖包,换个配置名,又可以愉快的额使用了:

1
2
3
4
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>

更新配置:

1
2
3
4
5
6
spirng:
cache:
type: caffeine
cache-names: api_cache
caffeine:
spec: maximumSize=300,expireAfterWrite=2m

通常SpringBoot默认的keyGenerator 是SimpleKeyGenerator,这个策略是以参数作为key值,如果参数为空的,就会返回SimpleKey[]字符串,这对于很多无参的方法的就有问题了
我们需要重新这个keyGenerator,实现 org.springframework.cache.interceptor.keyGenerator 这个接口即可,将key值设置为类名+方法名+参数名,这样就不会冲突了

1
2
3
4
5
6
7
8
9
10
11
12
@Bean
public KeyGenerator caffeineKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}

感觉无缝切换,继续使用吧!!!

制作背景

  • 有时候宅在家里实在不知道玩什么游戏
  • 英雄联盟都玩烂了
  • 哥们提议玩红警
  • 红警是单机啊,一个人玩另一个人怎么办,一个人打电脑有啥意思 =_=|
  • 找对战平台啊,首先下载安装了红警玩家自制的战网对战平台
  • 我个人电脑从来不安装杀毒软件,Windows Defender 一直报毒搞个不停
  • 战网的平台体验也很不好,消息弹个不停,感觉像广告软件
  • 后来换了腾讯对战平台,进入红警起个名字老说含有敏感信息,结果起了半个小时,MDZZ
  • 决定自己了解下对战平台的原理,打算自己写个简单好用的玩

原理

通过socket hook + udp,针对war3来说,支持tcp,先在本地通过hook模拟建立tcp连接,然后将tcp的数据转成外网udp数据发给外网服务器转发给其他客户端,客户端接收到后通过本地tcp
模拟连接转发到游戏进程。这个过程中通过中转服务器协助进行p2p。
JoyGame-zhihu

上面是知乎上的回答
用我自己的话说就是

使用JoyGameClient客户端,在本地创建了一个虚拟的IP地址,每一个客户端通过连接远程服务器形成了一个虚拟局域网,这样在游戏的【局域网】选择项中就能找到彼此,这样自然一方创建一个游戏,其他人都可以加入进来了就能愉快的玩耍了。底层通信使用的就是TCP和UDP连接,在同一个房间的玩家都会向服务器发送和下载游戏的实时数据。服务器会向房间里的玩家的客户端上转发数据包,这样就间接形成了一个局域网,就能在一起玩游戏啦。

使用

  • 解压,打开JoyGameClient.exe
  • 选择中间的网络服务器,因为你本地肯定是没有服务端的,只能连接远程部署好的服务器
    JoyGame-Login
  • 没有账号,就注册一个账号,注册成功后登录平台
    JoyGame-Login
  • 这是主界面
  • 接下来进入一个你想玩的游戏的房间
  • 设置你的游戏启动主程序
    JoyGame-Login
  • 下面可以设置启动时游戏的参数,比如玩红警时,加入参数 -win,可以窗口启动
  • 之后点启动,进入游戏就可找到在一个房间的小伙伴了
  • 使用都很简单,看一遍就会

特色

  • 可以聊天,发表情,可以加好友。。。额,这些好像没有什么特色
    JoyGame-Login

我想说

如果你想玩玩以前的一些怀旧游戏,或者你想看看该平台是如何操作实现联机的,还等什么,跟着Joy一起来玩吧
私聊我可以给你开个 VIP 、等级直接升到将军哦!虽然没什么用,纯粹装*

下载

0%