Java十大简单性能优化

关于“ web scale ”这个流行词有很多炒作,人们花了很多时间来重新组织他们的应用程序体系结构,以使其系统“规模化”。

但是什么扩展,我们如何确保可以扩展?

缩放的不同方面

上面提到的炒作主要是关于扩展负载 ,即确保一个适用于1个用户的系统也适用于10个用户,100个用户或数百万个用户。 理想情况下,您的系统应尽可能“无状态”,以便可以在网络中的任何处理单元上转移和转换真正保留的少量状态。 当负载是您的问题时,延迟可能就没有了,因此,如果单个请求花费50-100毫秒就可以了。 这通常也称为横向扩展

扩展的一个完全不同的方面是扩展性能 ,即,确保适用于1条信息的算法也适用于10条或100条或数百万条。 Big O Notation最好地描述了这种缩放是否可行。 延迟是扩展性能的杀手。 您想尽一切可能将所有计算保持在一台计算机上。 这通常也称为放大

如果有免费午餐之类的东西( 没有 ),我们可以无限期地结合扩大规模和扩大规模。 无论如何,今天,我们将研究一些非常简单的方法来改善性能。

大O符号

Java 7的ForkJoinPool以及Java 8的并行Stream有助于并行化内容,这在将Java程序部署到多核处理器计算机上时非常有用。 与在网络上的不同计算机上进行扩展相比,这种并行性的优势在于您几乎可以完全消除延迟影响,因为所有内核都可以访问同一内存。

但是,不要被并行性的效果所迷惑! 请记住以下两件事:

  • 并行主义吞噬了您的核心。 这对于批处理非常有用,但是对于异步服务器(例如HTTP)来说却是一场噩梦。 在过去的几十年中,我们使用单线程servlet模型是有充分的理由的。 因此,并行性仅在扩大规模时有用。
  • 并行性对算法的Big O表示法没有影响。 如果您的算法是O(n log n) ,并且让该算法在c核上运行,那么您仍然会拥有O(n log n / c)算法,因为c在算法复杂度上是微不足道的常数。 您将节省挂钟时间,但不会降低复杂性!

当然,提高性能的最好方法是降低算法复杂度。 当然,杀手是实现O(1)或准O(1) ,例如HashMap查找。 但这并不总是可能的,更不用说轻松了。

如果您不能降低复杂性,只要找到合适的位置,只要对算法真正重要的地方进行调整,您仍然可以获得很多性能。 假定算法的以下直观表示形式:

算法2

如果我们要处理单个数量级,该算法的总体复杂度为O(N 3 )O(N x O x P) 。 但是,在分析此代码时,您可能会发现一个有趣的场景:

  • 在开发框中,左分支( N -> M -> Heavy operation )是您可以在探查器中看到的唯一分支,因为OP的值在开发样本数据中很小。
  • 但是,在生产中,右分支( N -> O -> P -> Easy operationNOPE )确实会造成麻烦。 您的运营团队可能已经使用AppDynamics或DynaTrace或某些类似的软件解决了这一问题。

没有生产数据,您可能会Swift得出结论并优化“繁重的操作”。 您将其运送到生产环境,并且修复无效。

除了以下事实外,没有最佳的黄金法则:

  • 设计良好的应用程序更容易优化
  • 过早的优化不会解决任何性能问题,但是会使您的应用程序设计欠佳,从而使优化变得更加困难

足够的理论。 假设您已找到问题所在的正确分支。 很容易在生产中吹起一个非常简单的操作,因为它被称为很多次(如果NOP大)。 在不可避免的O(N 3 )算法的叶子节点存在问题的情况下,请阅读本文。 这些优化不会帮助您扩展规模。 他们将帮助您暂时节省客户的时间,将整个算法的困难改进推迟到以后!

以下是Java中最容易进行的10个性能优化:

1.使用StringBuilder

这几乎是所有Java代码中的默认设置。 尽量避免使用+运算符。 当然,您可能会争辩说它仍然只是StringBuilder语法糖,例如:

String x = "a" + args.length + "b";

…编译成

0  new java.lang.StringBuilder [16]3  dup4  ldc <String "a"> [18]6  invokespecial java.lang.StringBuilder(java.lang.String) [20]9  aload_0 [args]
10  arraylength
11  invokevirtual java.lang.StringBuilder.append(int) : java.lang.StringBuilder [23]
14  ldc <String "b"> [27]
16  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [29]
19  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [32]
22  astore_1 [x]

但是会发生什么,如果以后需要用可选部分修改String呢?

String x = "a" + args.length + "b";if (args.length == 1)x = x + args[0];

现在,您将拥有第二个StringBuilder ,它只是不必要地消耗了堆内存,从而给GC带来了压力。 改写这个:

StringBuilder x = new StringBuilder("a");
x.append(args.length);
x.append("b");if (args.length == 1);x.append(args[0]);

带走

在上面的示例中,如果您使用显式StringBuilder实例,或者依赖Java编译器为您创建隐式实例,则可能完全不相关。 但是请记住,我们在NOPE分支中 。 每个CPU周期我们都在浪费像GC这样愚蠢的东西或分配StringBuilder的默认容量,我们浪费的时间是N x O x P次。

根据经验,请始终使用StringBuilder而不是+运算符。 如果可以的话,如果您的String构建比较复杂,则可以在多个方法中保留StringBuilder引用。 这是jOOQ在生成复杂的SQL语句时所做的。 只有一个StringBuilder可以“遍历”您的整个SQL AST(抽象语法树)

为了大声喊叫,如果仍然有StringBuffer引用,请用StringBuilder替换它们。 您实际上几乎不需要同步正在创建的字符串。

2.避免使用正则表达式

正则表达式相对便宜且方便。 但是,如果您位于NOPE分支中 ,那么它们将是您最糟糕的事情。 如果您绝对必须在计算密集型代码节中使用正则表达式,则至少要缓存Pattern引用,而不要一直重新编译它:

static final Pattern HEAVY_REGEX = Pattern.compile("(((X)*Y)*Z)*");

但是如果你的正则表达式真的很傻

String[] parts = ipAddress.split("\\.");

……那么您真的最好使用普通的char[]或基于索引的操作。 例如,这个完全不可读的循环执行相同的操作:

int length = ipAddress.length();
int offset = 0;
int part = 0;
for (int i = 0; i < length; i++) {if (i == length - 1 || ipAddress.charAt(i + 1) == '.') {parts[part] = ipAddress.substring(offset, i + 1);part++;offset = i + 2;}
}

……这也说明了为什么您不应该进行任何过早的优化。 与split()版本相比,这是无法维护的。

挑战:读者中的聪明人可能会找到更快的算法。

带走

正则表达式很有用,但要付出一定的代价。 如果您深入了解NOPE分支 ,则必须不惜一切代价避免使用正则表达式。 提防各种使用正则表达式的JDK String方法,例如String.replaceAll()String.split()

请改用诸如Apache Commons Lang之类的流行库来进行String操作。

3.不要使用iterator()

现在,此建议实际上并不适用于一般用例,而仅适用于NOPE分支的深处。 但是,您应该考虑一下。 编写Java-5样式的foreach循环很方便。 您可以完全忘记循环内部,然后编写:

for (String value : strings) {// Do something useful here
}

但是,每次遇到此循环时,如果stringsIterable ,则将创建一个新的Iterator实例。 如果您使用ArrayList ,这将在堆上分配一个3 ints的对象:

private class Itr implements Iterator<E> {int cursor;int lastRet = -1;int expectedModCount = modCount;// ...

相反,您可以编写以下等效循环,并仅在堆栈上“浪费”一个int值,这非常便宜:

int size = strings.size();
for (int i = 0; i < size; i++) {String value : strings.get(i);// Do something useful here
}

…或者,如果您的列表没有真正改变,您甚至可以对其数组版本进行操作:

for (String value : stringArray) {// Do something useful here
}

带走

从可写性和可读性以及从API设计的角度来看,迭代器,Iterable和foreach循环都非常有用。 但是,它们为每次迭代在堆上创建一个小的新实例。 如果您多次运行此迭代,则要确保避免创建此无用的实例,而改为编写基于索引的迭代。

讨论区

关于上述部分的一些有趣的分歧(特别是用索引访问代替Iterator用法) 已经在Reddit上进行了讨论 。

4.不要调用该方法

有些方法简单昂贵。 在我们的NOPE分支示例中,叶子上没有这样的方法,但是您很可能有一个。 假设您的JDBC驱动程序需要经历难以置信的麻烦才能计算ResultSet.wasNull()的值。 您自己的SQL框架代码可能如下所示:

if (type == Integer.class) {result = (T) wasNull(rs, Integer.valueOf(rs.getInt(index)));
}// And then...
static final <T> T wasNull(ResultSet rs, T value) 
throws SQLException {return rs.wasNull() ? null : value;
}

每次您从结果集中获取一个int ,此逻辑将立即调用ResultSet.wasNull() 。 但是getInt()合同显示为:

返回:列值; 如果值为SQL NULL,则返回值为0

因此,对上述内容进行简单但可能很大的改进将是:

static final <T extends Number> T wasNull(ResultSet rs, T value
) 
throws SQLException {return (value == null || (value.intValue() == 0 && rs.wasNull())) ? null : value;
}

因此,这很容易:

带走

不要在算法的“叶子节点”中调用昂贵的方法,而要缓存调用,或者在方法合同允许的情况下避免调用。

5.使用原语和堆栈

上面的示例来自jOOQ ,它使用了很多泛型,因此被迫对byteshortintlong使用包装器类型-至少在泛型将在Java 10和项目Valhalla中实现特殊化之前。 但是您的代码中可能没有此约束,因此应采取所有措施替换:

// Goes to the heap
Integer i = 817598;

… 这样:

// Stays on the stack
int i = 817598;

使用数组时,情况变得更糟:

// Three heap objects!
Integer[] i = { 1337, 424242 };

… 这样:

// One heap object.
int[] i = { 1337, 424242 };

带走

当您深入了解NOPE分支时 ,应该非常警惕使用包装器类型。 可能会给GC带来很大压力,必须时刻加油清理GC。

一种特别有用的优化可能是使用某种原始类型并为其创建大型的一维数组,以及几个定界符变量以指示编码对象在数组上的确切位置。

trove4j是一个出色的原始集合库,它比您的平均int[]要复杂一些 ,它随LGPL一起提供。

例外

此规则有一个例外: booleanbyte值很少,因此无法完全由JDK缓存。 你可以写:

Boolean a1 = true; // ... syntax sugar for:
Boolean a2 = Boolean.valueOf(true);Byte b1 = (byte) 123; // ... syntax sugar for:
Byte b2 = Byte.valueOf((byte) 123);

对于其他整数基元类型的低值(包括charshortintlong

但是仅当您将它们自动装箱或调用TheType.valueOf() ,才调用构造函数!

除非确实需要新实例,否则切勿在包装器类型上调用构造函数。

这个事实还可以帮助您为同事写一个复杂的,愚蠢的愚人节玩笑

堆外

当然,您可能还想尝试堆外库,尽管它们更多是一个战略决策,而不是本地优化。

彼得·劳瑞(Peter Lawrey)和本·科顿(Ben Cotton)撰写的有关该主题的有趣文章是: OpenJDK和HashMap…安全地教老狗新手(超堆!)技巧

6.避免递归

像Scala这样的现代函数式编程语言鼓励使用递归,因为它们提供了将尾递归算法优化回迭代算法的方法 。 如果您的语言支持这种优化,则可能会很好。 但是即使如此,算法的最细微改动也可能会产生一个分支,从而阻止您的递归成为尾递归。 希望编译器能够检测到这一点! 否则,您可能会浪费大量的堆栈框架,而这些内容可能只使用了几个局部变量就已经实现了。

带走

除了以下内容外,没有什么要说的:当您深入NOPE分支时,始终喜欢迭代而不是递归。

7.使用entrySet()

当您要遍历Map ,同时需要键值时,必须有充分的理由编写以下内容:

for (K key : map.keySet()) {V value : map.get(key);
}

…而不是以下内容:

for (Entry<K, V> entry : map.entrySet()) {K key = entry.getKey();V value = entry.getValue();
}

当您在NOPE分支中时 ,无论如何,您都应该警惕地图,因为很多O(1)地图访问操作仍然很多。 而且访问也不是免费的。 但是至少,如果您不能没有地图,请使用entrySet()对其进行迭代! 无论如何,都有Map.Entry实例,您只需要访问它即可。

带走

在地图迭代期间同时需要键和值时,请始终使用entrySet()

8.使用EnumSet或EnumMap

在某些情况下,映射中可能的键数是预先已知的,例如在使用配置映射时。 如果该数字相对较小,则应真正考虑使用EnumSetEnumMap ,而不是常规的HashSetHashMap 。 通过查看EnumMap.put()可以很容易地解释这一点:

private transient Object[] vals;public V put(K key, V value) {// ...int index = key.ordinal();vals[index] = maskNull(value);// ...
}

此实现的本质是这样一个事实,即我们拥有一个索引值数组,而不是哈希表。 当插入一个新值时,我们要查找映射项的所有工作就是询问枚举的常量序数,该序数由Java编译器在每种枚举类型上生成。 如果这是一个全局配置映射(即仅一个实例),则提高的访问速度将帮助EnumMap大大优于HashMap ,后者可能使用较少的堆内存,但必须在每个键上运行hashCode()equals()

带走

EnumEnumMap是非常好的朋友。 每当您使用类似枚举的结构作为键时,请考虑实际上使这些结构成为枚举并将其用作EnumMap键。

9.优化您的hashCode()和equals()方法

如果您不能使用EnumMap ,至少要优化您的hashCode()equals()方法。 一个好的hashCode()方法至关重要,因为它将阻止对更昂贵的equals()进一步调用,因为它将为每个实例集生成更多不同的哈希存储桶。

在每个类层次结构中,您可能都有流行和简单的对象。 让我们看一下jOOQ的org.jooq.Table实现。

hashCode()的最简单,最快的实现方法是:

// AbstractTable, a common Table base implementation:@Override
public int hashCode() {// [#1938] This is a much more efficient hashCode()// implementation compared to that of standard// QueryPartsreturn name.hashCode();
}

…其中name只是表名。 我们甚至不考虑表的模式或任何其他属性,因为表名通常在数据库中足够不同。 另外,该name是一个字符串,因此它内部已经有一个缓存的hashCode()值。

该注释很重要,因为AbstractTable扩展了AbstractQueryPart ,它是任何AST(抽象语法树)元素的通用基本实现。 通用AST元素没有任何属性,因此它不能做任何假设来优化hashCode()实现。 因此,重写的方法如下所示:

// AbstractQueryPart, a common AST element
// base implementation:@Override
public int hashCode() {// This is a working default implementation. // It should be overridden by concrete subclasses,// to improve performancereturn create().renderInlined(this).hashCode();
}

换句话说,必须触发整个SQL呈现工作流以计算公共AST元素的哈希码。

equals()事情变得更加有趣

// AbstractTable, a common Table base implementation:@Override
public boolean equals(Object that) {if (this == that) {return true;}// [#2144] Non-equality can be decided early, // without executing the rather expensive// implementation of AbstractQueryPart.equals()if (that instanceof AbstractTable) {if (StringUtils.equals(name, (((AbstractTable<?>) that).name))) {return super.equals(that);}return false;}return false;
}

第一件事: 总是 (不仅在NOPE分支中 )提前中止每个equals()方法,如果:

  • this == argument
  • this "incompatible type" argument

请注意,如果您使用instanceof检查兼容类型,则后一个条件包括argument == null 。 之前,我们在“编码Java的10个微妙的最佳实践”中已经对此进行了博客撰写。

现在,在明显的情况下尽早中止比较之后,您可能还想在可以做出部分决策时就中止比较。 例如,jOOQ的Table.equals()Table.equals()是要使两个表相等,无论具体的实现类型如何,它们都必须具有相同的名称。 例如,这两个项目不可能相等:

  • com.example.generated.Tables.MY_TABLE
  • DSL.tableByName("MY_OTHER_TABLE")

如果argument 不能等于this ,并且如果我们可以轻松地进行检查,那么我们可以进行检查,如果检查失败,则中止。 如果检查成功,我们仍然可以从super进行更昂贵的实现。 鉴于Universe中的大多数对象不相等,我们将通过简化此方法来节省大量CPU时间。

有些对象比其他对象更平等

对于jOOQ,大多数实例实际上是由jOOQ源代码生成器生成的表,该表的equals()实现甚至得到了进一步优化。 其他数十种表类型(派生表,表值函数,数组表,联接表,数据透视表,公用表表达式等)可以保持其“简单”实现。

10.集合思考,而不是个别思考

最后但并非最不重要的一点是,它与Java不相关,但适用于任何语言。 此外,我们将离开NOPE分支,因为此建议可能只是帮助您从O(N 3 )迁移到O(n log n)或类似的东西。

不幸的是,许多程序员认为是简单的本地算法。 他们一步一步地解决问题,逐分支,逐循环,逐方法。 那就是命令式和/或函数式编程风格。 从纯命令式到面向对象(仍然命令式)再到函数式编程时,为“更大的画面”建模变得越来越容易,但是所有这些样式都缺少只有SQL,R和类似语言才能具备的功能:

声明式编程。

在SQL中( 并且我们很喜欢,因为它是jOOQ博客 ),您可以声明要从数据库中获取的结果,而不会产生任何算法含义。 然后,数据库可以考虑所有可用的元数据( 例如约束,键,索引等 ),以找出可能的最佳算法。

从理论上讲,从一开始,这就是SQL和关系演算背后的主要思想。 在实践中,SQL供应商仅在最近十年才实施了高效的CBO(基于成本的优化工具) ,因此请与我们保持在一起,直到2010年SQL最终释放出其全部潜力(大约是时间!)。

但是,您不必执行SQL即可进行集合思考。 集合/收藏/袋子/清单可提供所有语言和库。 使用集合的主要优点是您的算法将变得更加简洁。 编写起来非常容易:

SomeSet INTERSECT SomeOtherSet

而不是:

// Pre-Java 8
Set result = new HashSet();
for (Object candidate : someSet)if (someOtherSet.contains(candidate))result.add(candidate);// Even Java 8 doesn't really help
someSet.stream().filter(someOtherSet::contains).collect(Collectors.toSet());

有人可能会认为函数式编程和Java 8将帮助您编写更简单,更简洁的算法。 不一定是真的。 您可以将命令性的Java-7循环转换为功能性的Java-8 Stream集合,但是您仍在编写完全相同的算法。 编写类似SQL的表达式是不同的。 这个…

SomeSet INTERSECT SomeOtherSet

…可以由实施引擎以1000种方式实施。 正如我们今天所了解的那样,在运行INTERSECT操作之前,将两个集合自动转换为EnumSet也许是明智的。 也许我们可以并行化此INTERSECT而无需对Stream.parallel()进行低级调用。

结论

在本文中,我们讨论了在NOPE分支上完成的优化,即深入到高复杂度算法中。 在我们的案例中,作为jOOQ开发人员,我们对优化我们的SQL生成感兴趣:

  • 每个查询仅在单个StringBuilder上生成
  • 我们的模板引擎实际上是解析字符,而不是使用正则表达式
  • 我们会尽可能使用数组,尤其是在侦听器上进行迭代时
  • 我们避免了不必调用的JDBC方法
  • 等等…

jOOQ位于“食物链的底部”,因为它是(次)API,在调用离开JVM进入DBMS之前,我们的客户应用程序正在调用它。 位于食物链的底部意味着在jOOQ中执行的每一行代码都可能被称为N x O x P倍,因此我们必须热切地进行优化。

您的业​​务逻辑不在NOPE分支中 。 但是您自己的本地基础结构逻辑可能是(自定义SQL框架,自定义库等),应该根据我们今天所看到的规则进行审查。 例如,使用Java Mission Control或任何其他探查器。

翻译自: https://www.javacodegeeks.com/2015/02/top-10-easy-performance-optimisations-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php在苹果手机上传不了图片大小,ThinkPHP后台上传图片无默认尺寸解决方法

原标题&#xff1a;ThinkPHP后台上传图片无默认尺寸解决方法随着网站移动端的日益普及&#xff0c;对后台数据的兼容性要求也越来越高。后台数据涵盖范围不断扩大的同时&#xff0c;使得程序处理能力也必须逐步提高。使用ThinkPHP进行长沙网站开发时&#xff0c;后台kindeditor…

宝塔php gd库,宝塔面板安装 EasyImag – 一款最简单图床的安装体验

近日闲逛&#xff0c;发现了一款图床&#xff0c;一款开箱即食的简单图床程序。因为没有数据库所以安装起来也是异常简单&#xff0c;我们看看功能&#xff1a;支持设置图片质量支持仅登录后上传支持QQ截图&#xff0c;剪切板上传支持在线管理(增删改查)支持上传图片转换为指定…

批准Oracle IDM中的特定Web服务

关于Web服务端点的快速发布&#xff0c;OIM和SOA在与批准有关的场景中使用了Web服务端点- 基本内容&#xff0c;但对于初学者可能有用 。 Oracle IDM与SOA套件集成并利用其提供与批准相关的功能&#xff08;说实话&#xff0c;SOA相当丰富&#xff0c;并且也被用作Web服务连接…

Oracle15001,Oracle11gR2RAC环境DBCA创建数据库报错ORA-15055ORA-15001

在Oracle 11gR2 GridInfrastructure和Database软件安装完成之后&#xff0c;执行DBCA创建数据库到30%的时候报如下错误&#xff0c;点击OK后提示忽略并问题现象:在Oracle 11gR2 GridInfrastructure和Database软件安装完成之后&#xff0c;执行DBCA创建数据库到30%的时候报如下错…

针对新手的Java EE7和Maven项目–第8部分

第1部分 &#xff0c; 第2部分 &#xff0c; 第3部分 &#xff0c; 第4部分 &#xff0c; 第5部分 &#xff0c; 第6部分 &#xff0c; 第7部分 第8部分 自上一篇文章以来&#xff0c;这一系列教程已经有很长时间了。 是时候恢复并在我们的简单项目中添加新功能了。 正…

玩Weld-Probe –一站式查看CDI的所有方面

焊接3.0.0.Alpha4被释放 &#xff0c;而我一直坐在在DevConf.CZ一间会议室。 Jozef Hartinger&#xff08; jozefhartinger &#xff09;或多或少地在几分钟前告诉我有关此最新版本的新功能的信息。 有一个特别的功能真正引起了我的注意&#xff0c;它是新的焊接探针机制。 什…

linux cmake装在自己目录下,如何在Linux下安装cmake

全部展开OpenCV 2.2和更高版本需要使用Cmake生成生成文件&#xff0c;因此需要先安装cmake. 还有其他需要先安装cmake的软件1. 在Linux环境中打开Web浏览器&#xff0c;输入URL:mac cmake gui&#xff0c;找到最新版本的位置. 通常&#xff0c;发布了两个版本的开源软件: “源分…

Java Bootstrap:Dropwizard与Spring Boot

如何在尽可能短的时间内使准备就绪的Java应用程序投入生产&#xff1f; 我不是一个早起的人&#xff0c;所以有时需要一些时间才能启动“所有系统”提示。直到不久之前&#xff0c;这对于Java应用程序来说都是正确的&#xff0c;但是与发明贪睡功能不同闹钟&#xff0c;我们将在…

物理数据模型(PDM)-概念数据模型 (CDM)-面向对象模型 (OOM):适用于已经设计好数据库表结构了。...

步骤如下&#xff1a; 一、反向生成物理数据模型PDM 开发环境 PowerDesigner 15 ,SQL Server2005 &#xff08;1&#xff09;在开始逆向生成PDM图之前&#xff0c;需要为指定的数据库创建ODBC数据源。以Windows xp操作系统为例&#xff0c;选择“开始”/“运行”命令&#xff0…

MySQL作为Kubernetes服务,可从WildFly Pod访问

Kubernetes上使用Vagrant的Java EE 7和WildFly&#xff08;技术提示&#xff03;71&#xff09;介绍了如何在使用Kubernetes和Docker托管的WildFly上运行琐碎的Java EE 7应用程序。 Java EE 7应用程序是在世界范围内交付的动手实验室 。 它使用与WildFly捆绑在一起的内存数据库…

麒麟Linux启动目录,优麒麟目录结构介绍 系统入门必备

对于Linux爱好者来说&#xff0c;深入了解Linux文件目录结构的标准和每个目录的详细功能&#xff0c;对于我们用好Linux系统至关重要&#xff0c;下面就由小编给大家介绍下优麒麟系统的目录结构&#xff0c;PS: 同样适用于其他Linux发行版。查看系统的全部目录&#xff1a;* 在…

java课堂作业(一)

1、环境变量配置参见&#xff1a;http://www.cnblogs.com/dongwenbo/p/3282014.html window ---> preference ---> java ---> installed jres ---> add jres tomcat 配置&#xff1a;myeclipse ---> preferences ---> myeclipse enterprise workbench --->…

为什么我的JVM访问的内存少于通过-Xmx指定的内存?

“嘿&#xff0c;你能来看看奇怪的东西吗&#xff1f;” 这就是我开始研究一个支持案例的方式&#xff0c;该案例将我引向了这篇博客文章。 当前的特殊问题与不同的工具报告了有关可用内存的不同数字有关。 简而言之&#xff0c;一位工程师正在研究特定应用程序的过多内存使用…

linux怎么安装高德导航软件,高德地图车机版如何安装?高德地图车机版安装教程...

高德地图车机版是高德为汽车车载机提供的一个专用版本&#xff0c;对于车主们来说有时候用手机导航实在是非常不方便&#xff0c;不仅屏幕小而且还可能中途来个电话什么的。高德地图车机版可以帮你的车载机装上导航地图&#xff0c;就算你不想买导航设备也能让你的车子为你导航…

Dropwizard,MongoDB和Gradle实验

介绍 我使用Dropwizard&#xff0c;MongoDB和Gradle创建了一个小项目。 它实际上是从一个实验性的Guava缓存开始的&#xff0c;作为将计数器发送到MongoDB&#xff08;或任何其他DB&#xff09;的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来&#xff0c;我想创建某种接口…

在wp中,使用NavigationService.Navigate导航页面出现错误

我们在WP项目中采用页面导航时候&#xff0c;经常会使用以下代码 NavigationService.Navigate(new Uri("/Page1.xaml",UriKind.Relative));但是&#xff0c;有的时候会出现错误&#xff1a; "Error 1 An object reference is required for the non-static field…

SSDT – Error SQL70001 This statement is not recognized in this context-摘自网络

March 28, 2013 — arcanecode One of the most common errors I get asked about when using SQL Server Data Tools (SSDT) Database Projects is the error “This statement is not recognized in this context”. This is actually a pretty simple error to fix. Envisi…

带有JAX-RS和PrimeFaces的RESTful图表

通常&#xff0c;利用图表提供数据的可视表示很有用。 PrimeFaces提供制图解决方案&#xff0c;可轻松将数据的可视表示形式添加到Web和移动应用程序中。 如果将PrimeFaces图表组件与RESTful Web服务数据结合使用&#xff0c;我们可以创建自定义图表&#xff0c;以适合桌面和移…

UVAlive 6131 dp+斜率优化

这道题和06年论文《从一类单调性问题看算法的优化》第一道例题很相似。 题意&#xff1a;给出n个矿的重量和位置&#xff0c;这些矿石只能从上往下运送&#xff0c;现在要在这些地方建造m个heap&#xff0c;要使得&#xff0c;sigma距离*重量最小。 思路&#xff1a;O(n ^ 3)的…

c语言程序整数四则运算,c语言中三个整数随机的四则运算

满意答案hors10722014.01.06采纳率&#xff1a;58% 等级&#xff1a;12已帮助&#xff1a;18274人#include #include #include #define N 10 //随机出10道题目int main(){int num1, num2, num3, count0, result,resultTrue,flag;//result:用户输入结果 resultTrue:正确结果 …