1.Algorithm:https://leetcode-cn.com/problems/reverse-string-ii/

给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转。如果剩余少于 k 个字符,则将剩余的所有全部反转。如果有小于 2k 但大于或等于 k 个字符,则反转前 k 个字符,并将剩余的字符保持原样。

示例:

输入: s = “abcdefg”, k = 2
输出: “bacdfeg”

要求:

  1. 该字符串只包含小写的英文字母。
  2. 给定字符串的长度和 k 在[1, 10000]范围内。

参考代码如下:

//leetcode 541. 反转字符串 II

public class reverseStrii {
    public String reverseStr(String s, int k) {
        char[] a = s.toCharArray();
        for (int start = 0; start < a.length; start += 2 * k) {
            int i = start, j = Math.min(start + k - 1, a.length - 1);
            while (i < j) {
                char tmp = a[i];
                a[i++] = a[j];
                a[j--] = tmp;
            }
        }
        return new String(a);
    }
}

2.Review:https://shipilev.net/jvm/anatomy-quarks/10-string-intern/

String.intern

public String intern() 方法,

返回字符串对象的规范表示。String 类维护一个内部字符串池,初始为空。

调用 intern(),如果池中有字符串与调用的字符串 equals(Object) 结果相等,直接返回池中的字符串;否则,加入字符串池并返回对象引用。

— JDK Javadoc

java.lang.String

看起来 String 提供的接口可以操作内部字符串池进而优化内存,对吗?然而,这里有一个缺点:OpenJDK 的 String.intern() 是本地(native)实现,执行时会调用 JVM 把 String 存入本地 JVM 字符串池。由于 intern 是一个 JDK 与 VM 之间的接口,所以 VM 本地代码和 JDK 代码都需要处理字符串对象。

这种实现会带来下列影响:

  1. 每次调用 intern() 都要在 JDK 与 JVM 之间的接口,浪费时间。
  2. intern() 性能取决于 HashTable 本地实现,落后于高性能 Java 实现,在并发访问情况下尤其如此。
  3. 由于 Java 字符串是本地 VM 结构的引用,它们成为 GC root set 一部分。许多情况下,需要在 GC 暂停时进行额外处理。

String.intern() 为 OpenJDK 提供了访问本地 JVM StringTable 方法。使用 intern 时需要关注吞吐量、内存占用和暂停时间,这些都有可能让用户等待。人们很容易低估这些警告带来的影响。手工实现去重或 intern 方法运行更加可靠。因为它们工作在 Java 端,只是普通的 Java 对象,可以更好地设置和重新调整大小。而且在不再需要时也可以完全丢弃。GC 辅助的字符串去重的确更好地减轻了负担。

在实际项目中,从性能开销的热点路径上去除 String.intern() 或者采用手工实现去重方法有助于性能优化。请不要没有深思熟虑就使用 String.intern(),好吗?

翻译,参考

https://www.javazhiyin.com/41778.html

3.Tip:https://mp.weixin.qq.com/s/ZVtzGy4UFmFd5cqRBILgfg

工欲善其事必先利其器,IDEA的调试功能,很多人可能用的不全,建议全面了解一下,提高效率。

4.share:

saga内容总结