开发工具分享
  • 首页
  • 计算科学
  • 文化旅游
  • 项目和网站
    • OSSEZ 计算技术
    • USRealEstate 社区
    • 地区文化
    • CWIKI.US
    • BUG.OSSEZ.COM
    • RSS.OSSEZ.COM
CWIKIUS.CN
一个有独立思考和温度的清新站
Computer Science

Jackson-jr 对比 Jackson

关于Jackson-jr 对比 Jackson 的内容,有人在做了一张下面的图。     简单点来说就 Jackson-jr 是Jackson 的轻量级应用,因为我们在很多时候都用不到 Jackson 的很多复杂功能。 对很多应用来说,我们可能只需要使用简单的 JSON 读写即可。 如我们用不到什么复杂的功能,并且使用了 Jackson-jr 能够满足你的项目使用的话,就直接使用 Jackson-jr 即可。 如发现 Jackson-jr 没有办法满足你的所有需求的时候,可以再切换到传统的 Jackson 包。   https://www.isharkfly.com/t/jackson-jr-jackson/15708

2024年05月04日 0Comments 543Browse 0Like Read more
Computer Science

Java Jackson-jr 库是干什么用的

Jackson-jr 是一个轻量级的Java JSON 处理库。这个库被设计用来替代 Jackson 的复杂性。对比 Jackson 的复杂 API,Jackson-jr 的启动速度更快,包大小更小。 虽然Jackson databind(如ObjectMapper)是通用数据绑定的良好选择,但它的占用空间(Jar包大小)和启动开销在某些领域可能存在问题:比如移动端,特别是对于轻量使用(读或写)。这种情况下,完整的Jackson API是让人接受不了的。 由于所有这些原因,Jackson 官方决定创建一个更简单、更小的库:Jackson-jr。它仍旧构建在 Streaming API 之上,但不依赖于 databind 和annotation。因此,它的大小(jar和运行时内存使用)要小得多,它的API非常紧凑,所以适合APP等移动端。 它仅仅只依赖了 jackson-core 模块,所以体积上控制得非常的好。Jackson 单单三大核心模块大小合计1700KB左右(320 + 70 + 1370)。而Jackson-jr的体积控制在了95KB(就算加上core模块的320也不到500KB)。 针对实际开发的情况,很多时候我们只需要对 JSON 数据进行读取和写入,至于一些过于复杂和强大的属性,我们可能也用不上,因此针对一些 JSON 数据使用场景比较单一的情况,Jackson-jr 就显得更有优势了。 所以,Jackson-jr 的主要情况就是在针对 JSON 格式的读写上面,如果你只需要简单的读和些,Jackson-jr 通常是你的一个选择。 性能 有关 JSON 处理数据的能力,Github 上有个项目进行了一些测试。 项目的地址为:GitHub - fabienrenaud/java-json-benchmark: Performance testing of serialization and deserialization of Java JSON libraries 根据项目测试的结果来看,Jackson 的处理能力是所有参加测试的包的性能最好的。     Jackson-jr 和 Jackson 是同一个社区的产品,因此性能上面完全不需要担心。   https://www.isharkfly.com/t/java-jackson-jr/15709

2024年05月04日 0Comments 379Browse 0Like Read more
Computer Science

Gitea 上传用户签名

在 Gitea 的用户管理部分,有一个 SSH 和 GPG 的选项。     单击这个选项,可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户,可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。     单击这个导出,就会出现一个新的界面,把这个新界面中的内容复制粘贴到添加 GPG 的 Key 的对话框中即可。 如果你是用的 GitHub 的话,也可以同样的操作,也是拷贝这个内容。 通常这个内容只需要拷贝 1 次就可以了,如果更换了 Key,那么 GPG 还需要重新复制一下。     上图显示了 GPG key 的大致情况。 当完成签名后在界面中显示的图片如下图:     看起来好看些了。 https://www.isharkfly.com/t/gitea/15707

2024年05月03日 0Comments 487Browse 0Like Read more
Computer Science

Java 项目编译提示 --release 错误

提示的错误信息: INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project core-java-9: Compilation failure [ERROR] exporting a package from system module java.base is not allowed with --release [ERROR] [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn <args> -rf :core-java-9     问题和解决 出现上面错误的原因是 JDK9 开始,–release 和 --add-exports 参数不能同时使用。 在我们的项目编译的时候添加了 --add-exports 参数。 这个会在 JDK 9 的时候报错。     我们可以把这个参数从编译环境中删除。   https://www.isharkfly.com/t/java-release/15702

2024年05月02日 0Comments 395Browse 0Like Read more
Computer Science

键盘更新计划

作为 IT 搬砖人,一直都认为键盘没有什么太大关系。 每次都是公司发什么用什么。     但随着用几年后,发现现在的键盘经常出问题,比如说调节音量的时候通常莫名其妙的卡死,要不就是最大音量要不就是最小音量。 按键 M 不知道什么原因巨难按下去,有时候还感觉莫名其妙的卡在哪里。 回想这么多年,用的都是 104 键,一直没有来得及用什么比较好的机械键盘,随后发现键盘这东西就应该是生产力工具,不好的键盘确实有点感觉影响心情,遂决定换个键盘。 选型 正是对罗技见面的一些些失望,所以就先给看看有什么比较好的选项。 键盘用途:键盘的主要用途是工作需要,基本上不玩游戏,所以,游戏键盘就在考虑范围之内了,同时也并不需要类似游戏键盘的那种炫酷灯光。 连通性:随时可能需要会联通 iPad 和电脑,主流编程使用的计算机是 Windows 的计算机,不太希望使用 2.4G 的接收器,因为这个 2.4 G的接收器还需要占据一个 USB 接口。上网刷评测的时候说在连通性上,有线的肯定是要好过于无线的,但日常的工作就是调试程序,输入文本和邮件沟通。这种延迟对应该不会构成任何影响。简单点来说就是需要具有无线联通能力。 手感:已经有点受够了罗技这种普通键盘的手感了,想换下机械键盘。还记得读书的那个时候感觉都是机械键盘的天下和带轨迹球的鼠标,现在全是光电鼠标了,绕了一圈又绕回去了。 真是时间是一个挺有意思的东西,用了一圈居然又用回去了。 罗技 如果说考虑键盘就不得不说罗技这个牌子了。 用过的很多键盘都是罗技的,主要是性能比较稳定,兼容性没有问题,随便插上就能用,同时也因为家里和公司用的都是这个牌子,键盘鼠标换用也很方便。 这次主要原因也是罗技的键盘出了问题,所以想着就能不能抛开这牌子换一个牌子看看。 罗技也又机械键盘,上面的价格在 179 美元左右,叫做 MX 机械键盘系列。 MX Mechanical大概不是机械键盘里的顶格产品。但是MX Mechanical的优势在于对罗技生态的兼容性极佳,Options+Flow使用体验还是非常棒的。如果你使用的是罗技办公鼠标尤其是MX系列的旗舰办公鼠标的话,这个吸引力会非常大。 NuPhy 这个键盘应该就是在高颜值上,每款做得都非常漂亮。 对我们这种工科屌丝来说可能吸引并不是很大。     不过从官网上发的图片来看,每款都是那么炫酷。 HHKB 这个牌子还是最近在搜索键盘的时候才记起来还有这么个牌子。 最主要的是在日本以外的市场不是那么好买,更重要的是这个价格还是有点高的。如果不是特别发烧的这种级别,可能大部分人都不会入手这个牌子。 更何况这个键盘本身就是小键盘,对一般的使用者来说还是有一定的使用曲线的,不是和其他键盘都一样拿来就能用的那种。 可能还真是念旧了,第一眼居然是看上了 HHKB,而且还选的是和最古老的机械键盘相同的颜色布局。 下单 纠结了一顿饭的时间,决定下单 HHKB。 亚马逊上的价格是 299,然后查询了下官网,官网的价格也是 299。 本着多一事不如少一事的想法,就官网下单了,如果不着急的话,可以选择免邮费,就是时间长点。     有一种 3000 块钱的包可以买,1 块钱的邮费绝对不能出的感觉。 虽然有输入 Coupon 折扣码的地方,但 Google 到处找了下都没有找到可用的 Coupon,感觉就是压根不打算打折的意思。 有点过分了。 收到键盘时候的样子。     是非常简单的包装盒,说以前是有键帽拔除器的,现在这个也没有了,貌似也省掉了。   有点找到了大学时候学习计算机的感觉。     收到键盘后的第一件事情 收到键盘后的第一件时间就是调整 DIP。 本文提及的键盘配置方案,适用于包括 HHKB Pro 2 在内的大部分现役产品。 对 HHKB 机身后方的六个开关,我推荐使用如下的配置: Windows: 开启 1 3 4 号开关 MacOS: 开启 2 3 4 号开关 第 6 号开关是自动休眠。 关于自动休眠的情况就是,如果设置了自动休眠,那么休眠的时间是 30 分钟,当键盘休眠 后,不能通过敲打任何键盘的方式重新进行连接。 经过我的试验,是需要重新摁一下电源键才能重新打开电源。 如果第 6 号开关设置为 ON 的话,那么就不会对键盘进行休眠。唯一的问题就是电源消耗更快。 对我们的日常使用来说,应该还是需要把这个开关设置为不要休眠。 Windows 和 Mac 的模式 有关 Windows 和 Mac 模式的区别上,可以看看这个表。     从表里面可以看出来,HHKB 键盘对 Mac 的电脑兼容更多的模式。 主要区别就是对比 Windows 模式而言,Mac 的模式还多了一个对电源的控制。 可以通过 HHKB 的功能键对电源进行控制,Windows 模式下,没有这个功能。   https://www.isharkfly.com/t/topic/15659

2024年05月01日 0Comments 448Browse 0Like Read more
Computer Science

Java Maven 编译资源文件拷贝错误 dirCompressed.zip failed with MalformedInputException:

完整的错误信息为: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources (default-resources) on project core-java-io: filtering C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-java-io\src\main\resources\dirCompressed.zip to C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-java-io\target\classes\dirCompressed.zip failed with MalformedInputException: Input length = 1 -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn <args> -rf :core-java-io     问题和解决 出现上面错误的原因是在资源文件进行拷贝的时候的校验问题。 我们需要拷贝一个 zip 的资源文件,但是 Maven 在拷贝的时候会进行校验,这会导致拷贝失败。 所以我们可以添加配置: <nonFilteredFileExtensions> <nonFilteredFileExtension>zip</nonFilteredFileExtension> </nonFilteredFileExtensions> 到 插件 maven-resources-plugin 中。 添加后的完整插件配置为: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven-resources-plugin.version}</version> <configuration> <encoding>UTF-8</encoding> <nonFilteredFileExtensions> <nonFilteredFileExtension>zip</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin>     当完成上面的配置后,资源文件就可以顺利在编译的时候拷贝了。   https://www.isharkfly.com/t/java-maven-dircompressed-zip-failed-with-malformedinputexception/15694

2024年05月01日 0Comments 554Browse 0Like Read more
Computer Science

Java image-processing 包依赖错误

错误的信息为: [ERROR] Failed to execute goal on project image-processing: Could not resolve dependencies for project com.ossez:image-processing:jar:0.0.2-SNAPSHOT: Failed to collect dependencies at org.openimaj:core-image:jar:1.3.10 -> org.op enimaj:core:jar:1.3.10 -> vigna.dsi.unimi.it:jal:jar:20031117: Failed to read artifact descriptor for vigna.dsi.unimi.it:jal:jar:20031117: The following artifacts could not be resolved: vigna.dsi.unimi.it:jal:pom:20031117 (absen t): Could not transfer artifact vigna.dsi.unimi.it:jal:pom:20031117 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [openimaj-maven (http://maven.openimaj.org/, default, releases+snapshots), openimaj-snapshots-maven (http://snapshots.openimaj.org/, default, releases+snapshots)] -> [Help 1]     问题和解决 错误的原因在于 :vigna.dsi.unimi.it:jal:jar:20031117 这个包没有找到。 这个包的仓库地址为:ICM Repository (http://maven.icm.edu.pl/artifactory/repo/) 需要把这个仓库添加到项目中。   https://www.isharkfly.com/t/java-image-processing/15691  

2024年05月01日 0Comments 413Browse 0Like Read more
Computer Science

Java 使用 Maven 编译时插件提示 拷贝错误

提示的具体信息为: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources (default-resources) on project core-java-8: filtering C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-java -8\src\main\resources\formats_fr.properties to C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-java-8\target\classes\formats_fr.properties failed with MalformedInputException: Input length = 1 -> [Help 1]     问题和解决 上面提示的错误原因在于属性文件使用了非英语字符,但是属性文件没有使用 UTF-8 编码。 这会导致程序识别的错误。     检查属性文件的编码格式,需要修改为 UTF-8 编码。   https://www.isharkfly.com/t/java-maven/15690

2024年05月01日 0Comments 410Browse 0Like Read more
Computer Science

创建基于时间的 UUID

概述 在本文中,我们将会 对 UUIDs 和基于时间的 UUIDs(time-based UUIDs) 进行一些探讨。 当我们在对基于时间的 UUIDs 进行选择的时候,总会遇到一些好的方面和不好的方面,如何进行选择,也是我们将要简要探讨的内容。 同时我们还会对可能会使用类库进行一些比较和探索,以便于我们更好的做出选择。 UUIDs 和 基于时间的 UUIDs UUID 的全称是 Universally Unique Identifier,中文为通用唯一识别码。 当生成 UUID 的时候,系统总会自动生成一个 128 位的 UUID。基于 UUID 的生产算法的不同,我们会有不同的版本。 UUID 的主要目的就是用来在全世界中唯一标识一个数据,而且需要保证生成的 UUID 在全世界范围内是不重复的。因此我们可以用来标识一个上下文,包括数据库系统,计算机系统中的消息,分布式系统中的对象等等。 为了实现这个目标,我们需要确保哪怕是在同一个时间瞬间生成的 UUID 也是不相同,这样能够让我们更好的利用 UUID 在分布式计算机系统中标识存在的对象。 基于时间的 UUID,通过字面就可以了解到,这个 UUID 是基于时间的,实际上这个 UUID 存在 UUID 设计中的第一版。 这个版本是基于随机数的,使用的基数为每 100 纳秒为一个单位,时间的起点为1582年10月15日。同时还需要加上当前计算机的网卡物理地址(MAC)。 在后续的版本中,UUID (v6 和 v7)也是基于时间的 UUID 生成算法,可以说是基于 UUID v1 的更新版本。 UUID v1 因为是基于时间的,所以具有排序功能,这个在对数据库的设计上就很有帮助,当我们使用 UUID v1 来作为 PK(主键)的时候,我们就知道了,我们创建的这条记录的时间戳是什么时候,这个对我们在对数据进行调试和问题分析的时候就很有帮助了。 有优势就自然会有劣势,因为我们是基于时间创建 UUID 的,那么在同一个系统产生 UUID 冲突的可能性就会大很多,假设在同一个时间点,我们创建了很多个 UUID,那么大概率就会有出现冲突,重复出现的情况。 在本文的后部分,我们会对这个可能出现的情况进行一些探索。 另外一个原因,就是在 UUID v1 版本中使用主机地址这种做法会潜在的增加系统的安全性问题。这就是 UUID v6 尝试希望解决的问题。 对比程序 为了对可能出现的 UUID 冲突进行演示。我们尝试使用程序来对比可能出现 UUID 冲突的可能性。 这个程序,将会创建 128 个线程,在每个线程中将会生成 100,000 个 UUID。 首先我们对需要使用的变量来进行一些初始化: int threadCount = 128; int iterationCount = 100_000; Map<UUID, Long> uuidMap = new ConcurrentHashMap<>(); AtomicLong collisionCount = new AtomicLong(); long startNanos = System.nanoTime(); CountDownLatch endLatch = new CountDownLatch(threadCount); 如上面的程序所表示的内容,我们定义了 128 个线程,在这 128 个线程中,我们会循环 100,000 次。 同时,我们还初始化了一个 ConcurentHashMap 把我们生成的 UUID 存储到 ConcurentHashMap 中。 同时,我们还会记录出现 UUID 冲突的次数。 为了记录程序的性能,我们对程序开始时间和程序的结束也都进行了存储。在最后我们定义了一个 latch 等待所有线程的执行完成。 当定义完成后变量后,我们就需要启动线程并对线程序进行执行。 for (long i = 0; i < threadCount; i++) { long threadId = i; new Thread(() -> { for (long j = 0; j < iterationCount; j++) { UUID uuid = Generators.timeBasedGenerator().generate(); Long existingUUID = uuidMap.put(uuid, (threadId * iterationCount) + j); if(existingUUID != null) { collisionCount.incrementAndGet(); } } endLatch.countDown(); }).start(); } 在 UUID 的创建过程中,我们使用了 fasterxml 包中的 Generators,这个 Generators 使用的是 java.util.UUID 类来创建的。 在创建 UUID v1 的使用,使用 fasterxml 是我们常用的做法。 当 UUID 创建后,我们就把创建好的 UUID 存储到 Map 中,UUID 为 map 的 Key,当我们的 UUID 重复出现冲突的时候,Map 将会提示错误,我们程序就会捕获这个错误,然后把出现错误的计数器 + 1。 endLatch.await(); System.out.println(threadCount * iterationCount + " UUIDs generated, " + collisionCount + " collisions in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos) + "ms"); 在程序的最后,CountDownLatch 的 await() 方法会等待所有的线程完成。 当所有线程完成后,我们就会把结果打印在计算机屏幕上。 下面就让我们开始对程序进行运行。 12800000 UUIDs generated, 0 collisions in 16913ms 上面出现了程序的运行结果,我们可以看到并没有出现…

2024年04月29日 0Comments 657Browse 0Like Read more
Computer Science

Java 中将 UUID 存储为 Base64 字符串

概述 使用 Base64 编码来对 UUID(Universally Unique Identifiers) 存储在一些特定的场合被广泛的使用。使用 Base64 对比直接使用 UUID 进行存储来说能够更多的节约空间。   本文对这方面的相关内容和问题进行探讨。   在这里,使用 Base64 来对 UUID 进行存储,涉及到一些类型的转换的。Base64 是编码算法,在实际使用的时候我们更多会用到 Byte 数组的方式来进行编码的。这样我们就比较明确在对其进行 Base64 转换之前,我们应该要先干什么了。 使用 byte[] 和 Base64.Encoder Base64.Encoder 就能够提供 byte[] 的 Base64 编码了,我们先使用这个最简单的方式来进行处理。 编码 首先我们需要给出的 UUID 位中创建出我们需要的 byte 数组。 我们先获得 UUID 的 most significant bits 和 least significant bits,然后放入我们 byte 数组中的 0-7 和 8-15 的位置。 程序代码如下: private byte[] convertToByteArray(UUID uuid) { byte[] result = new byte[16]; long mostSignificantBits = uuid.getMostSignificantBits(); fillByteArray(0, 8, result, mostSignificantBits); long leastSignificantBits = uuid.getLeastSignificantBits(); fillByteArray(8, 16, result, leastSignificantBits); return result; } 上面的代码中还有一个 fillByteArray 方法,这个方法,这个方法将会把我们的 bit 存如 byte array 数组中,同时还会移动 8 位。 方法的代码如下: void fillByteArray(int start, int end, byte[] result, long bits) { for (int i = start; i < end; i++) { int shift = i * 8; result[i] = (byte) ((int) (255L & bits >> shift)); } } 当我们获得 byte 数组后,我们就可以调用 JDK 的 Base64.Encoder 方法来直接进行编码了成一个 Base64 加密字符串了。 完整的测试代码如下: UUID originalUUID = UUID.fromString("cc5f93f7-8cf1-4a51-83c6-e740313a0c6c"); @Test void givenEncodedString_whenDecodingUsingBase64Decoder_thenGiveExpectedUUID() { String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw=="; byte[] uuidBytes = convertToByteArray(originalUUID); String encodedUUID = Base64.getEncoder().encodeToString(uuidBytes); assertEquals(expectedEncodedString, encodedUUID); } 解码 把我们获得的 UUID Base64 字符串进行解码,我们可以使用完全相反的方法: @Test public void givenEncodedString_whenDecodingUsingBase64Decoder_thenGiveExpectedUUID() { String expectedEncodedString = "UUrxjPeTX8xsDDoxQOfGgw=="; byte[] decodedBytes = Base64.getDecoder().decode(expectedEncodedString); UUID uuid = convertToUUID(decodedBytes); } 首先把 Base64 字符串解码成 Byte 数组,然后调用我们的转换方法,把我们获得 byte 数组转换成为 UUID 对象。 UUID convertToUUID(byte[] src) { long mostSignificantBits = convertBytesToLong(src, 0); long leastSignificantBits = convertBytesToLong(src, 8); return new UUID(mostSignificantBits, leastSignificantBits); } 在上面的方法中,我们分别对 UUID 中需要使用的 most significant bits 和 less significant bits 分别进行转换,然后再组合在一起。 转换的方法如下: long convertBytesToLong(byte[] uuidBytes, int start) { long result = 0; for(int i = 0; i < 8; i++) { int shift = i * 8; long bits = (255L & (long)uuidBytes[i + start]) <<…

2024年04月28日 0Comments 613Browse 0Like Read more
1…4950515253…303
Archives
  • June 2026
  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
Categories
  • Computer Science (2,367)
    • Confluence (663)
    • Gradle (12)
  • U.S. (517)
  • 文化旅游 (146)

COPYRIGHT © 2020 CWIKIUS. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

湘ICP备2020018253号-1