maven profile

maven profile http://haohaoxuexi.iteye.com/blog/1900568 4 profile介绍 4.1 profile简介 profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。具体的激活条件有哪些我在后文会讲到。 4.2 profile的定义位置 对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。 (1) 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。 (2) 针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的".m2"目录下。 (3) 全局的profile配置。全局的profile是定义在Maven安装目录下的"conf/settings.xml"文件中的。 4.3 profile中能定义的信息 profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。 4.3.1 profile定义在settings.xml中 当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有 <repositories>、<pluginRepositories>和<properties>。定义在<properties>里面的键值对可以在pom.xml中使用。 4.3.2 profile定义在pom.xml中 定义在pom.xml中的profile可以定义更多的信息。主要有以下这些: <repositories> <pluginRepositories> <dependencies> <plugins> <properties> <dependencyManagement> <distributionManagement> 还有build元素下面的子元素,主要包括: <defaultGoal> <resources> <testResources> <finalName> 4.4 profile的激活方式 Maven给我们提供了多种不同的profile激活方式。比如我们可以使用-P参数显示的激活一个profile,也可以根据环境条件的设置让它自动激活等。下面将对它们一一进行介绍: 4.4.1 使用activeByDefault设置激活 先看下面一个配置 <profiles> <profile> <id>profileTest1</id> <properties> <hello>world</hello> </properties> true</activeByDefault> </activation> </profile> <profile> <id>profileTest2</id> <properties> <hello>andy</hello> </properties> </profile> </profiles> 我们可以在profile中的activation元素中指定激活条件,当没有指定条件,然后指定activeByDefault为true的时候就表示当没有指定其他profile为激活状态时,该profile就默认会被激活。所以当我们调用mvn package的时候上面的profileTest1将会被激活,但是当我们使用mvn package –P profileTest2的时候将激活profileTest2,而这个时候profileTest1将不会被激活。 4.4.2 在settings.xml中使用activeProfiles指定处于激活状态的profile 我们可以在settings.xml中使用activeProfiles来指定需要激活的profile,这种方式激活的profile将所有情况下都处于激活状态。比如现在我们定义了如下两个profile <profiles> <profile> <id>profileTest1</id> <properties> <hello>world</hello> </properties> </profile> <profile> <id>profileTest2</id> <properties> <hello>andy</hello> </properties> </profile> </profiles> 这里的profile可以是定义在settings.xml中的,也可以是定义在pom.xml中的。这个时候如果我们需要指定profileTest1为激活状态,那么我们就可以在settings.xml中定义activeProfiles,具体定义如下: ...

Created 6066-01-06 · Updated 9096-10-09 · 2 min · 237 words · -

Maven 类包冲突的三个解决技巧, mvn dependency:tree

Maven类包冲突终极三大解决技巧 mvn dependency,tree http://ian.wang/106.htm Maven对于新手来说是《步步惊心》,因为它包罗万象,博大精深,因为当你初来乍到时,你就像一个进入森林的陌生访客一样迷茫。 Maven对于老手来说是《真爱配方》,因为它无所不能,利如刀锋,使用Maven做开发,如饮美酒如悦美人。 Maven对于新手来说,最痛苦的一件事莫过于包之间的冲突,由于Maven的依赖传递性,当你引入一个依赖类时,其身后的依赖类也一起如过江之鲫纷至沓来了。 举例 A依赖于B及C,而B又依赖于X、Y,而C依赖于X、M,则A除引B及C的依赖包下,还会引入X,Y,M的依赖包 (一般情况下了,Maven可通过<scope>等若干种方式控制传递依赖) 。 这里有一个需要特别注意的,即B和C同时依赖于X,假设B依赖于X的1.0版本,而C依赖于X的2.0版本,A究竟依赖于X的1.0还是2.0版本呢? 这就看Classloader的加载顺序了,假设Classloader先加载X_1.0,而它就不会再加载X_2.0了,如果A恰恰希望使用X_2.0呢,血案就这样不期而遇了。 三大技巧 第一板斧:找到传递依赖的鬼出在哪里? dependency:tree是把照妖照,pom.xml用它照照,所有传递性依赖都将无处遁形,并且会以层级树方式展现,非常直观。 以下就是执行dependency:tree后的一个输出: 引用 [INFO] - maven-dependency-plugin:2.1:tree (default-cli) @ euler-foundation - [INFO] com.hsit:euler-foundation:jar:0.9.0.1-SNAPSHOT [INFO] +- com.rop:rop:jar:1.0.1:compile [INFO] | +- org.slf4j:slf4j-api:jar:1.7.5:compile [INFO] | +- org.slf4j:slf4j-log4j12:jar:1.7.5:compile [INFO] | +- log4j:log4j:jar:1.2.16:compile [INFO] | +- commons-lang:commons-lang:jar:2.6:compile [INFO] | +- commons-codec:commons-codec:jar:1.6:compile [INFO] | +- javax.validation:validation-api:jar:1.0.0.GA:compile [INFO] | +- org.hibernate:hibernate-validator:jar:4.2.0.Final:compile [INFO] | +- org.codehaus.jackson:jackson-core-asl:jar:1.9.5:compile [INFO] | +- org.codehaus.jackson:jackson-mapper-asl:jar:1.9.5:compile [INFO] | +- org.codehaus.jackson:jackson-jaxrs:jar:1.9.5:compile [INFO] | +- org.codehaus.jackson:jackson-xc:jar:1.9.5:compile ...

Created 17176-02-17 · Updated 9096-10-09 · 2 min · 375 words · -

Java Unix Socket 2

java unix socket <dependency> <groupId>uk.co.caprica</groupId> juds</artifactId> <version>0.94.1</version> </dependency> 维护记录 时间 修改内容 原因 2026-10-09 修复本地 Hugo 构建的 Raw HTML 警告:代码/配置放入代码块,正文中的尖括号占位符改为行内代码;文件重命名为 unix-socket-2.md;title 改为「Java Unix Socket 2」;categories 改为 Java 正文中的 HTML/XML 片段被当作原始 HTML 丢弃;文件名/URL/标题按规范调整

Created 29296-02-29 · Updated 9096-10-09 · 1 min · 31 words · -

Netty HTTP 文件服务器

netty http文件服务器 http://krisjin.github.io/2015/02/14/netty-file-server/ Http介绍 Http(超文本传输协议)协议是建立在TCP传输协议之上的应用成协议,Http由于便捷、快速的方式,适用于分布式超媒体信息系统。Http是目前Web开发的主流协议,基于Http的应用非常广泛,因此掌握HTTP的开发非常重要。由于netty的HTTP协议栈是基于netty的NIO通信框架开发的,所以netty的HTTP协议也是异步非阻塞的。 具体的关于HTTP及Netyy的实现细节在以后的章节在写,先上实例代码: 实例代码 服务端: public class HttpFileServer { public void run(final int port, final String url) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap boot = new ServerBootstrap(); boot.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536)); ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); ch.pipeline().addLast("fileServerHandler", new HttpFileServerHandler(url)); } }); ChannelFuture cf =boot.bind("127.0.0.1",port).sync(); System.out.println("Http文件目录服务器启动: [http://127.0.0.1](http://127.0.0.1):"+port+url); cf.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws InterruptedException { String url="/src/main/java/"; new HttpFileServer().run(8080, url); } } 服务端handler ...

Created 20206-03-20 · Updated 9096-10-09 · 3 min · 631 words · -

Java 数组合并

java 数组 合并 http://blog.csdn.net/jaycee110905/article/details/9179227 Java中如何把两个数组合并为一个 标签: JavaArray合并数组 2013-06-26 14:54 22185人阅读 评论(1) 收藏 举报 分类: JAVA (39) 目录(?)[+] http://freewind.me/blog/20110922/350.html 在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题。但是如何才能把代码写得高效简洁,却还是值得思考的。这里介绍四种方法,请参考选用。 一、apache-commons 这是最简单的办法。在apache-commons中,有一个ArrayUtils.addAll(Object[], Object[])方法,可以让我们一行搞定: String[] both = (String[]) ArrayUtils.addAll(first, second); 其它的都需要自己调用jdk中提供的方法,包装一下。 为了方便,我将定义一个工具方法concat,可以把两个数组合并在一起: static String[] concat(String[] first, String[] second) {} 为了通用,在可能的情况下,我将使用泛型来定义,这样不仅String[]可以使用,其它类型的数组也可以使用: static <T> T[] concat(T[] first, T[] second) {} 当然如果你的jdk不支持泛型,或者用不上,你可以手动把T换成String。 二、System.arraycopy() static String[] concat(String[] a, String[] b) { String[] c= new String[a.length+b.length]; System.arraycopy(a, 0, c, 0, a.length); System.arraycopy(b, 0, c, a.length, b.length); return c; } 使用如下: ...

Created 25256-03-25 · Updated 9096-10-09 · 2 min · 255 words · -

DbUnit

DbUnit http://yangzb.iteye.com/blog/947292 博客分类: QC 单元测试XML数据结构OraclePostgreSQL 相信做过单元测试的人都会对JUnit 非常的熟悉了,今天要介绍的DbUnit(http://dbunit.sourceforge.net/ ) 则是专门针对数据库测试的对JUnit 的一个扩展,它可以将测试对象数据库置于一个测试轮回之间的状态。鉴于目前国内介绍DbUnit 的系统教程比较少见,本文将分从理论和实例两个方面带你领略DbUnit 的精彩世界。 DbUnit 设计理念 熟悉单元测试的开发人员都知道,在对数据库进行单元测试时候,通常采用的方案有运用模拟对象(mock objects)和stubs 两种。通过隔离关联的数据库访问类,比如JDBC 的相关操作类,来达到对数据库操作的模拟测试。然而某些特殊的系统,比如利用了EJB 的CMP(container-managed persistence) 的系统,数据库的访问对象是在最底层而且很隐蔽的,那么这两种解决方案对这些系统就显得力不从心了。 DBUnit 的设计理念就是在测试之前,备份数据库,然后给对象数据库植入我们需要的准备数据,最后,在测试完毕后,读入备份数据库,回溯到测试前的状态; 而且又因为DBUnit 是对JUnit 的一种扩展,开发人员可以通过创建测试用例代码,在这些测试用例的生命周期内来对数据库的操作结果进行比较。 DbUnit 测试基本概念和流程 基于DbUnit 的测试的主要接口是IDataSet 。IDataSet 代表一个或多个表的数据。 可以将数据库模式的全部内容表示为单个IDataSet 实例。这些表本身由Itable 实例来表示。 IDataSet 的实现有很多,每一个都对应一个不同的数据源或加载机制。最常用的几种 IDataSet 实现为: FlatXmlDataSet : 数据的简单平面文件 XML 表示 QueryDataSet : 用 SQL 查询获得的数据 DatabaseDataSet : 数据库表本身内容的一种表示 XlsDataSet : 数据的excel 表示 一般而言,使用DbUnit 进行单元测试的流程如下: 1 根据业务,做好测试用的准备数据和预想结果数据,通常准备成xml 格式文件。 2 在setUp() 方法里边备份数据库中的关联表。 3 在setUp() 方法里边读入准备数据。 4 对测试类的对应测试方法进行实装: 执行对象方法,把数据库的实际执行结果和预想结果进行比较。 ...

Created 13136-04-13 · Updated 9096-10-09 · 3 min · 517 words · -

Netty File Upload 文件上传

netty 文件上传 http://blog.csdn.net/mcpang/article/details/41140409 【初学与研发之NETTY】netty4之文件上传 标签: netty4文件上传 2014-11-15 04:35 6005人阅读 评论(29) 收藏 举报 分类: JAVA (48) Netty (6) 版权声明: 本文为博主原创文章,未经博主允许不得转载。 客户端: public class UpLoadClient { private StringBuffer resultBuffer = new StringBuffer(); private EventLoopGroup group = null; private HttpDataFactory factory = null; private Object waitObject = new Object(); private ChannelFuture future = null; public UpLoadClient(String host, int port) throws Exception { this.group = new NioEventLoopGroup(); this.factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); Bootstrap b = new Bootstrap(); b.option(ChannelOption.TCP_NODELAY, true); b.option(ChannelOption.SO_SNDBUF, 1048576*200); b.option(ChannelOption.SO_KEEPALIVE, true); b.group(group).channel(NioSocketChannel.class); b.handler(new UpLoadClientIntializer()); this.future = b.connect(host, port).sync(); } public void uploadFile(String path) { if(path == null) { System.out.println("上传文件的路径不能为null..."); return; } File file = new File(path); if (!file.canRead()) { System.out.println(file.getName() + "不可读..."); return; } if (file.isHidden() || !file.isFile()) { System.out.println(file.getName() + "不存在..."); return; } try { HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, ""); HttpPostRequestEncoder bodyRequestEncoder = new HttpPostRequestEncoder(factory, request, false); bodyRequestEncoder.addBodyAttribute("getform", "POST"); bodyRequestEncoder.addBodyFileUpload("myfile", file, "application/x-zip-compressed", false); List<InterfaceHttpData> bodylist = bodyRequestEncoder.getBodyListAttributes(); if (bodylist == null) { System.out.println("请求体不存在..."); return; } HttpRequest request2 = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, file.getName()); HttpPostRequestEncoder bodyRequestEncoder2 = new HttpPostRequestEncoder(factory, request2, true); bodyRequestEncoder2.setBodyHttpDatas(bodylist); bodyRequestEncoder2.finalizeRequest(); Channel channel = this.future.channel(); if(channel.isActive() && channel.isWritable()) { channel.writeAndFlush(request2); if (bodyRequestEncoder2.isChunked()) { channel.writeAndFlush(bodyRequestEncoder2).awaitUninterruptibly(); } bodyRequestEncoder2.cleanFiles(); } channel.closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } } public void shutdownClient() { // 等待数据的传输通道关闭 group.shutdownGracefully(); factory.cleanAllHttpDatas(); } public boolean isCompleted() { while(waitObject != null) { //当通道处于开通和活动时,处于等待 } if(resultBuffer.length() > 0) { if("200".equals(resultBuffer.toString())) { resultBuffer.setLength(0); return true; } } return false; } private class UpLoadClientIntializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("decoder", new HttpResponseDecoder()); pipeline.addLast("encoder", new HttpRequestEncoder()); pipeline.addLast("chunkedWriter", new ChunkedWriteHandler()); pipeline.addLast("dispatcher", new UpLoadClientHandler()); } } private class UpLoadClientHandler extends SimpleChannelInboundHandler<HttpObject> { private boolean readingChunks = false; private int succCode = 200; protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { if (msg instanceof HttpResponse) { HttpResponse response = (HttpResponse) msg; succCode = response.getStatus().code(); if (succCode == 200 && HttpHeaders.isTransferEncodingChunked(response)) { readingChunks = true; } } if (msg instanceof HttpContent) { HttpContent chunk = (HttpContent) msg; System.out.println("【响应】"+succCode+">>"+chunk.content().toString(CharsetUtil.UTF_8)); if (chunk instanceof LastHttpContent) { readingChunks = false; } } if (!readingChunks) { resultBuffer.append(succCode); ctx.channel().close(); } } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { waitObject = null; } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { resultBuffer.setLength(0); resultBuffer.append(500); System.out.println("管道异常: " + cause.getMessage()); cause.printStackTrace(); ctx.channel().close(); } } } 服务端: ...

Created 24246-05-24 · Updated 9096-10-09 · 6 min · 1159 words · -

nftables

nftables 这里有张图 https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks nftables 是一个新式的数据包过滤框架,旨在替代现用的 iptables、ip6tables、arptables 和 ebtables 的新的包过滤框架。nftables 诞生于 2008 年,2013 年底合并到 Linux 内核,从 Linux 内核 3.13 版本开始大多数场景下 nftables 已经可以使用,但是完整的支持(即:nftables 优先级高于 iptables)应该是在 Linux 内核 3.15 版本。 nftables 旨在解决现有 {ip/ip6}tables 工具存在的诸多限制。相对于旧的 iptables,nftables 最引人注目的功能包括:改进性能、支持查询表、事务型规则更新、所有规则自动应用等等。 nftables 主要由三个组件组成:内核实现、libnl netlink 通信和 nftables 用户空间。其中内核提供了一个 netlink 配置接口以及运行时规则集评估,libnl 包含了与内核通信的基本函数,用户空间可以通过新引入的命令行工具 nft 和用户进行交互。 nft 可以通过在寄存器中储存和加载来交换数据。也就是说,它的语法与 iptables 不同。但 nft 可以利用内核提供的表达式去模拟旧的 iptables 命令,维持兼容性的同时获得更大的灵活性。简单来说,nft 是 iptables 及其衍生指令(ip6tables 和 arptables )的超集。 nftables 的特点 nftables 拥有一些高级的类似编程语言的能力,例如:定义变量和包含外部文件,即拥有使用额外脚本的能力。nftables 也可以用于多种地址簇的过滤和处理。 不同于 iptables, nftables 并不包含任何的内置表,需要哪些表并在这些表中添加什么处理规则一切由管理员决定。 表包含规则链,规则链包含规则。 nftables 相较于 iptables 的优点 更新速度更快 在 iptables 中添加一条规则,会随着规则数量增多而变得非常慢。这种状况对 nftables 而言就不存在了,因为 nftables 使用原子的快速操作来更新规则集合。 ...

Created 25256-05-25 · Updated 9096-10-09 · 4 min · 825 words · -

Maven Dependency Inheritance 依赖与继承

maven 依赖 继承 Project A 被 Project B 调用 比如 A 里有 mockito的jar包, B要引用A , 从而不需要在B里直接引用mockito的jar包,而且A 包里的自建代码也可以用起来。 关键点在于 A 的pom里不能 用 test scope来藏起来A里面的jar ,这样B就无法继承到了。 Maven依赖范围及依赖传递 一: 依赖范围scope 共5种,compile (编译)、test (测试)、runtime (运行时)、provided、system 不指定,则依赖范围默认为compile. compile:编译依赖范围,在编译,测试,运行时都需要。 test: 测试依赖范围,测试时需要。编译和运行不需要。如Junit runtime: 运行时依赖范围,测试和运行时需要。编译不需要。如JDBC驱动包 provided:已提供依赖范围,编译和测试时需要。运行时不需要。如servlet-api system:系统依赖范围。本地依赖,不在maven中央仓库。 二: 依赖的传递 A->B(compile) 第一关系: a依赖b compile B->C(compile) 第二关系: b依赖c compile 当在A中配置 <dependency> <groupId>com.B</groupId> B</artifactId> <version>1.0</version> </dependency> 则会自动导入c包。关系传递如下表: 第一 第二 compile test provided runtime compile compile runtime test test test ...

Created 5056-07-05 · Updated 9096-10-09 · 1 min · 145 words · -

PreparedStatementCache

PreparedStatementCache http://www.cnblogs.com/alipayhutu/archive/2013/04/18/3029171.html 如何理解PreparedStatementCache,以及如何使用 为节约键盘敲击次数,记PreparedStatement为PS, PreparedStatementCache为PSCache,并且所有的SQL使用的绑定变量。 原理: http://www.dbafree.net/?p=287 http://agapple.iteye.com/blog/838286 http://singleant.iteye.com/blog/1298837 使用: 使用ps. sql里用?占位,等待被替换。例如,select * from table1 where user_name = ? and age > ? 启用pscache。 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> .... <property name="poolPreparedStatements" value="true" /> <property name="maxOpenPreparedStatements" value="10" /> .... </bean> 解析后的PS缓存,与重复利用。 sql语句,被发送到DB server端,经一系列处理 (语法解析、语义解析、结构优化) ,转化为一个树型结构 (sql, string -> tree) 。 3.1 sql解析后 (string -> tree) ,如何将ps放到pscache里? 首先,澄清个概念。执行树这个不是在应用客户端的,是在oracle服务器那边,server中也有pscache. 再者是说,只要客户端开启了PSCache,那么CS端都会缓存住这些个树 (尽管C端维护的结构可能简单一点) 。 底层会缓存 (LRU替换) ,用户不用关心。 3.2 假如pscache中,有一棵树是select * from table1 where user_name = ? and age > ? ,现在并发来了50个线程,都要用这棵树,如何复用? 执行树是一个具体的执行步骤了,是oracle服务器底层的具体执行步骤,所以再多的并发,直接拿过来用就是了,跟并发没有很多的关系。 可以理解为一个非状态的公共方法,就可以了,多个线程直接调用,复用这个方法,不存在瓶颈。 本质上来说,是oracle底层"包揽了"。底层逻辑: 根据sql (String及参数类型等各种信息) ,计算出一个key,看它在pscache里是否存在。 ...

Created 22226-09-22 · Updated 9096-10-09 · 1 min · 103 words · -

远程桌面, freerdp, rdesktop

远程桌面, freerdp, rdesktop freerdp pacman -S freerdp xfreerdp /u:"user0" /v:192.168.50.182:3389 xfreerdp /v:192.168.50.9:3389 /u:"wiloon" /p:password0 /size:1680x1024 +clipboard xfreerdp /v:192.168.50.6:3389 /u:"wiloon" /p:password0 /size:1680x1024 +clipboard freerdp-shadow-cli freerdp-shadow-cli -auth /port:12345 https://www.mankier.com/1/freerdp-shadow-cli# windows 远程桌面 剪切板 http://www.cnblogs.com/hobinly/archive/2012/09/20/2694708.htmlT2001V00000087FG3 这几天遇到远程桌面控制服务器时, 无法剪切、粘贴一些东西, 上网搜了一下, 原来是 rdpclip.exe(remote desktop clipboard)不起作用了。此程序负责管理本地机与远程服务器之间共享剪切板,它运行在远程服务器上。 解决方法: 打开任务管理器-〉结束此进程 (rdpclip.exe) 点击任务管理器菜单"文件-〉新建任务",在输入框中输入"rdpclip",确定 linux连接到windows远程桌面 windows设置 系统属性>远程桌面 选择 “允许远程连接到此计算机”, 取消选择 “公允许运行使用网络级别身份验证的远程桌面计算机连接” linux rdesktop rdesktop 192.168.50.104 -g 1400x900 -u '<username>' -p <password> -r clipboard:CLIPBOARD # 非3389端口 rdesktop 192.168.50.104:3390 -g 1400x900 -u '<username>' -p <password> -r clipboard:CLIPBOARD # 域控用户 rdesktop 192.168.50.104 -g 1400x900 -u '<domain>\<username>' -p <password> -r clipboard:CLIPBOARD rdesktop 192.168.50.104 -g 1400x900 -u 'AD\<username>' -p <password> -r clipboard:CLIPBOARD rdesktop -g 1024x768 -d 24 hostname -u user0 -p password0 # PRIMARYCLIPBOARD 不稳定,用CLIPBOARD # rdesktop -g 1020x685 -d 24 192.168.1.199 -r clipboard:PRIMARYCLIPBOARD rdesktop -g 1020x685 -d 24 192.168.1.199 -r clipboard:CLIPBOARD # -M 使用本地鼠标 rdesktop 是UNIX 和Linux 系统的一个远程桌面连接软件,它通过MicrosoftWindows NT、Windows 2000 提供的终端服务(Terminal Services)以及WindowsXP 的远程桌面服务(Remote Desktop),能在Linux系统下远程登录Windows的窗口系统并使用。 ...

Created 18186-10-18 · Updated 9096-10-09 · 2 min · 246 words · -

gradle maven snapshot

gradle maven snapshot configurations.all { // check for updates every build resolutionStrategy.cacheChangingModulesFor 0, ‘seconds’ } dependencies { compile group: “group”, name: “projectA”, version: “1.1-SNAPSHOT”, changing: true } https://discuss.gradle.org/t/how-to-get-gradle-to-download-newer-snapshots-to-gradle-cache-when-using-an-ivy-repository/7344 gradle maven plugin https://docs.gradle.org/current/userguide/publishing_maven.html#header gradle v5.3.1 group = "com.wiloon.group0" version = "0.0.1-SNAPSHOT" plugins { `java-library` `maven-publish` id("com.gradle.build-scan") version "2.2.1" } tasks.register<Jar>("sourcesJar") { from(sourceSets.main.get().allJava) archiveClassifier.set("sources") } tasks.register<Jar>("javadocJar") { from(tasks.javadoc) archiveClassifier.set("javadoc") } publishing { publications { create<MavenPublication>("maven") { from(components["java"]) artifact(tasks["sourcesJar"]) artifact(tasks["javadocJar"]) } } repositories { maven { val releasesRepoUrl = "http://nexus.wiloon.com/repository/maven-releases" val snapshotsRepoUrl = "http://nexus.wiloon.com/repository/maven-snapshots" url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl) credentials { username = "admin" password = "password" } } } } 维护记录 时间 修改内容 原因 2026-10-09 修复本地 Hugo 构建的 Raw HTML 警告:代码/配置放入代码块,正文中的尖括号占位符改为行内代码;categories 改为 Java 正文中的 HTML/XML 片段被当作原始 HTML 丢弃;文件名/URL/标题按规范调整

Created 6066-11-06 · Updated 9096-10-09 · 1 min · 118 words · -

c basic, c, c lang, c 语言

c basic, c, c lang, c 语言 hello world vim main.c #include <stdio.h> int main(){ printf("hello world!\n"); return 0; } gcc main.c ./a.out # 也可以不使用 a.out 这个名字,我们自己对其进行命名: gcc main.c -o hello ./hello 预处理(或称预编译) 预处理(或称预编译)是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。预处理指令指示在程序正式编译前就由编译器进行的操作,可放在程序中任何位置。 预处理是C语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。 C语言提供多种预处理功能,主要处理#开始的预编译指令,如宏定义(#define)、文件包含(#include)、条件编译(#ifdef)等。合理使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。 头文件, header 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件: 程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件,需要使用 C 预处理指令 #include 来引用它。前面我们已经看过 stdio.h 头文件,它是编译器自带的头文件。 引用头文件相当于复制头文件的内容,但是我们不会直接在源文件中复制头文件的内容,因为这么做很容易出错,特别在程序是由多个源文件组成的时候。 A simple practice in C 或 C++ 程序中,建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件。 引用头文件的语法 使用预处理指令 #include 可以引用用户和系统头文件。它的形式有以下两种: #include <file> 这种形式用于引用系统头文件。它在系统的标准列表中搜索名为 file 的文件。在编译源代码时,您可以通过 -I 选项把目录前置在该列表前。 #include "file" #include #include 命令是预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置;可以标识出只有在特定条件下才会被编译的某一段程序代码;可以定义类似标识符功能的宏,在编译时, 预处理器会用别的文本取代该宏。 预处理器如何找到头文件 由给定的 C 语言实现版本决定 #include 命令所指定文件的搜索路径。同时,也由实现版本决定文件名是否区分大小写。对于命令中使用尖括号指定的文件 (<文件名>) , 预处理器通常会在特定的系统路径下搜索, 例如, 在 Unix 系统中, 会搜索路径 /usr/include, /usr/local/include 对于命令中用双引号指定的文件 (“文件名”) , 预处理器通常首先在当前目录下寻找,也就是包含该程序其他源文件的目录。如果在当前目录下没有找到,那么预处理器也会搜索系统的 include 路径。 文件名中可以包含路径。 但如果文件名中包含了路径,则预处理器只会到该目录下寻找。 ...

Created 16166-11-16 · Updated 9096-10-09 · 2 min · 380 words · -

tmux

tmux ~/.tmux.conf set -g mouse on set-window-option -g mode-keys vi #可以设置为vi或emacs set-window-option -g utf8 on #开启窗口的UTF-8支持 Tmux 是一个终端复用器 (terminal multiplexer) 窗格快捷键 下面是一些窗格操作的快捷键。 Ctrl+b %: 划分左右两个窗格。 Ctrl+b ": 划分上下两个窗格。 Ctrl+b : 光标切换到其他窗格。是指向要切换到的窗格的方向键,比如切换到下方窗格,就按方向键↓。 Ctrl+b ;: 光标切换到上一个窗格。 Ctrl+b o: 光标切换到下一个窗格。 Ctrl+b {: 当前窗格与上一个窗格交换位置。 Ctrl+b }: 当前窗格与下一个窗格交换位置。 Ctrl+b Ctrl+o: 所有窗格向前移动一个位置,第一个窗格变成最后一个窗格。 Ctrl+b Alt+o: 所有窗格向后移动一个位置,最后一个窗格变成第一个窗格。 Ctrl+b x: 关闭当前窗格。 Ctrl+b !: 将当前窗格拆分为一个独立窗口。 Ctrl+b z: 当前窗格全屏显示,再使用一次会变回原来大小。 Ctrl+b Ctrl+: 按箭头方向调整窗格大小。 Ctrl+b q: 显示窗格编号。 https://www.ruanyifeng.com/blog/2019/10/tmux.html sudo pacman -S tmux $ 重命名当前Session ...

Created 2026-12-02 · Updated 9096-10-09 · 2 min · 336 words · -

NMT, Native Memory Tracking

NMT, Native Memory Tracking NMT for Hotspot VM is turned off by default. Turn this feature on using JVM command line option -XX:NativeMemoryTracking=[off | summary | detail] 注意,根据Java官方文档,开启NMT会有5%-10%的性能损耗; 访问NMT数据 JDK提供了jcmd命令来访问NMT数据: jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB] 配置项 说明 summary 只打印打印按分类汇总的内存 detail 打印按分类汇总的内存用法、virtual memory map和每次内存分配调用 baseline 创建内存快照,以比较不同时间的内存差异 summary.diff 打印自上次baseline到现在的内存差异,显示汇总信息 detail.diff 打印自上次baseline到现在的内存差异, 显示详细信息 shutdown 关闭NMT功能,NMT can be shutdown using jcmd utility, but can not start/restart using jcmd ...

Created 6066-02-06 · Updated 9096-10-09 · 1 min · 110 words · -

Retained Heap

Retained Heap http://supercharles888.blog.51cto.com/609344/1347144 为了开始研究,我们希望在memory 溢出时候能自动生成heap dump文件,为此,我们在运行时候添加JVM 参数: -XX:+HeapDumpOnOutOfMemoryError 然后,我们来做一系列实验来逐步研究各个有趣的问题。 实验1: 我们先来研究最简单的memory leak例子。我们先构造一个POJO类Person,这个Person类就是一般的java 类,然后我们构造一个ArrayList,然后在一个无限循环中一直放这个Person类的实例,因为Person类和ArrayList都在堆上,而ArrayList因为是强引用,所以无法被GC回收, (因为我们List一直在用并没有摧毁) 所以一旦ArrayList所占用的堆内存填满整个heap size时候,heap就溢出了。 POJO类代码是: package com.charles.research; /** * * 这是一个Person类,我用它来撑满heap * @author charles.wang * */ public class Person { private String name; private String sex; private int age; public Person( String name,String sex,int age){ this.name=name; this.sex=sex; this.age=age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 然后我们创建ArrayList,并且无限向其中添加Person类对象的方法是: ...

Created 7076-02-07 · Updated 9096-10-09 · 2 min · 416 words · -

ThreadLocal

ThreadLocal ThreadLocal 是什么 弱引用 避免内存溢出的操作 开放地址法解决 hash 冲突 各种内部类 线程本地变量有时会简写为 TLV, Thread Local Variables ThreadLocal 是什么 ThreadLocal 是线程的局部变量, 也就是说这个变量是线程独有的。 通常情况下, 我们创建的变量是可以被任何一个线程访问并修改的。而使用 ThreadLocal 创建的变量只能被当前线程访问, 其他线程则无法访问和修改。 变量是同一个, 但是每个线程都使用同一个初始值, 也就是使用同一个变量的一个新的副本, 这种情况下 TreadLocal 就非常有用。 应用场景: 当很多线程需要多次使用同一个对象, 并且需要该对象具有相同初始值的时候, 最适合使用TreadLocal。 事实上,从本质上讲,就是每个线程都维持一个 MAP,而这个map的key就是TreadLocal,而值就是我们set的那个值,每次线程在get的时候,都从自己的变量中取值,既然从自己的变量中取值,那就肯定不存在线程安全的问题。总体来讲,TreadLocal这个变量的状态根本没有发生变化。它仅仅是充当了一个key的角色,另外提供给每一个线程一个初始值。如果允许的话,我们自己就能实现一个这样的功能,只不过恰好JDK就已经帮助我们做了这个事情。 使用TreadLocal维护变量时, TreadLocal为每个使用该变量的线程提供独立地变量副本, 所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。从线程的角度看,目标变量对象是线程的本地变量,这也是类名中Local所需要表达的意思。 TreadLocal的四个方法 void set(Object val),设置当前线程的线程局部变量的值 Object get () 返回当前线程所对用的线程局部变量。 void remove() 将当前线程局部变量的值删除,目的是为了减少内存的占用,线程结束后,局部变量自动被GC Object initValue() 返回该线程局部变量的初始值,使用protected修饰,显然是为了让子类覆盖而设计的。 ThreadLocalMap HashMap 的数据结构是数组+链表 ThreadLocalMap的数据结构仅仅是数组 HashMap 是通过链地址法解决 hash 冲突的问题 ThreadLocalMap 是通过开放地址法来解决 hash 冲突的问题 HashMap 里面的Entry 内部类的引用都是强引用 ThreadLocalMap里面的Entry 内部类中的key 是弱引用,value 是强引用 对象存放在哪里 在Java中, 栈内存归属于单个线程, 每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。 ...

Created 24246-03-24 · Updated 9096-10-09 · 3 min · 619 words · -

pthread

pthread code #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void* xc(void* arg){ char* c=(char*)arg; printf("参数%s \n",c); int i=0; for (;i<10;i++){ printf("循环%d\n",i); if(i==5){ pthread_exit(1090000000); } } return 100000222; } void main(){ pthread_t tid; pthread_create(&tid,NULL,xc,"线程!!!!"); void *status; pthread_join(tid,&status); printf("返回%d\n",(int)status); } pthread_create pthread.h是UNIX环境创建线程函数头文件 #include<pthread.h> int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,void * ( *start_rtn)(void *),void *restrict arg); extern int pthread_create (pthread_t *__restrict __newthread, const pthread_attr_t *__restrict __attr, void *(*__start_routine) (void *), void *__restrict __arg) __THROWNL __nonnull ((1, 3)); 若成功则返回0,否则返回出错编号 返回成功时,由 __newthread 指向的内存单元被设置为新创建线程的线程ID。 __attr 参数用于制定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能指针参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。 linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。 由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。 由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。参数 第一个参数为指向线程标识符的指针。 第二个参数用来设置线程属性。 第三个参数是线程运行函数的起始地址。 最后一个参数是运行函数的参数。 另外,在编译时注意加上-lpthread参数,以调用静态链接库。因为pthread并非Linux系统的默认库示例 打印线程 IDs #include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> pthread_t ntid; void printids(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid); } void \*thr_fn(void \*arg) { printids("new thread: "); return((void *)0); } int main(void) { int err; err = pthread_create(&ntid, NULL, thr_fn, NULL); if (err != 0) printf("can't create thread: %s\n", strerror(err)); printids("main thread:"); sleep(1); exit(0); } $ gcc main.c -lpthread ...

Created 26266-03-26 · Updated 9096-10-09 · 2 min · 340 words · -

Guava cache

Guava cache http://www.cnblogs.com/peida/p/Guava_Cache.html 缓存,在我们日常开发中是必不可少的一种解决性能问题的方法。简单的说,cache 就是为了提升系统性能而开辟的一块内存空间。 缓存的主要作用是暂时在内存中保存业务系统的数据处理结果,并且等待下次访问使用。在日常开发的很多场合,由于受限于硬盘IO的性能或者我们自身业务系统的数据处理和获取可能非常费时,当我们发现我们的系统这个数据请求量很大的时候,频繁的IO和频繁的逻辑处理会导致硬盘和CPU资源的瓶颈出现。缓存的作用就是将这些来自不易的数据保存在内存中,当有其他线程或者客户端需要查询相同的数据资源时,直接从缓存的内存块中返回数据,这样不但可以提高系统的响应时间,同时也可以节省对这些数据的处理流程的资源消耗,整体上来说,系统性能会有大大的提升。 缓存在很多系统和架构中都用广泛的应用,例如: 1.CPU缓存 2.操作系统缓存 3.本地缓存 4.分布式缓存 5.HTTP缓存 6.数据库缓存 等等,可以说在计算机和网络领域,缓存无处不在。可以这么说,只要有硬件性能不对等,涉及到网络传输的地方都会有缓存的身影。 Guava Cache是一个全内存的本地缓存实现,它提供了线程安全的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,性能好。 Guava Cache有两种创建方式: cacheLoader callable callback 通过这两种方法创建的cache,和通常用map来缓存的做法比,不同在于,这两种方法都实现了一种逻辑——从缓存中取key X的值,如果该值已经缓存过了,则返回缓存中的值,如果没有缓存过,可以通过某个方法来获取这个值。但不同的在于cacheloader的定义比较宽泛,是针对整个cache定义的,可以认为是统一的根据key值load value的方法。而callable的方式较为灵活,允许你在get的时候指定。 cacheLoader方式实现实例: @Test public void TestLoadingCache() throws Exception{ LoadingCache<String,String> cahceBuilder=CacheBuilder .newBuilder() .build(new CacheLoader<String, String>(){ @Override public String load(String key) throws Exception { String strProValue="hello "+key+"!"; return strProValue; } }); System.out.println("jerry value:"+cahceBuilder.apply("jerry")); System.out.println("jerry value:"+cahceBuilder.get("jerry")); System.out.println("peida value:"+cahceBuilder.get("peida")); System.out.println("peida value:"+cahceBuilder.apply("peida")); System.out.println("lisa value:"+cahceBuilder.apply("lisa")); cahceBuilder.put("harry", "ssdded"); System.out.println("harry value:"+cahceBuilder.get("harry")); } 输出: ...

Created 31316-03-31 · Updated 9096-10-09 · 3 min · 496 words · -

Java jps

java jps jps位于jdk的bin目录下,其作用是显示当前系统的java进程情况,及其id号。 jps相当于Solaris进程工具ps。不象"pgrep java"或"ps -ef grep java",jps并不使用应用程序名来查找JVM实例。因此,它查找所有的Java应用程序,包括即使没有使用java执行体的那种 (例如,定制的启动 器) 。另外,jps仅查找当前用户的Java进程,而不是当前系统中的所有进程。 -h: help -l: 输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名 -m: 输出传递给main 方法的参数,在嵌入式jvm上可能是null, 在这里,在启动main方法的时候,我给String[] args传递两个参数。hollis,chuang,执行jsp -m: -v: 输出传递给JVM的参数 在这里,在启动main方法的时候,我给jvm传递一个参数: -Dfile.encoding=UTF-8,执行jps -v: 位置 我们知道,很多Java命令都在jdk的JAVA_HOME/bin/目录下面,jps也不例外,他就在bin目录下,所以,他是java自带的一个命令。 功能 jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。 原理 jdk中的jps命令可以显示当前运行的java进程以及相关参数,它的实现机制如下: java程序在启动以后,会在java.io.tmpdir指定的目录下,就是临时文件夹里,生成一个类似于hsperfdata_User的文件夹,这个文件夹里 (在Linux中为/tmp/hsperfdata_{userName}/) ,有几个文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。 至于系统的参数什么,就可以解析这几个文件获得。 hollis@hos:/tmp/hsperfdata_hollis$ pwd /tmp/hsperfdata_hollis hollis@hos:/tmp/hsperfdata_hollis$ ll total 48 drwxr-xr-x 2 hollis hollis 4096 4月 16 10:54 ./ drwxrwxrwt 7 root root 12288 4月 16 10:56 ../ ...

Created 5056-05-05 · Updated 9096-10-09 · 2 min · 243 words · -