‘好’得边界

昨晚写JVM收集器的选择,说到编程中到处都是TradeOff,想起了前几天QQ群的一些讨论;

问:怎么样的一个工程才算是比较好的工程

群里面比较多的答复是;

比如有VCS啦,能够DevOps啦,还有关注代码质量啦。

但是在我看来,这些都没说到点子上。我认为一个好的工程应该是和其应用场景及生命周期相关的

Example 1:

我写了一个HelloWorld想学习一门新的语言,比如Java,那么这时候我们只需要一个Vim,一个JDK就足够了,就是一个好的工程了

Example 2:

我做了一个工具,能够自动的收集所在计算机的负载数据,我需要的数据在很长范围内是不会增加或者改变的,那么我随便一个IDE,怎么写得快就怎么写,这样可以快速使用,连VCS都可以不用有

Example 3:

我对外声称了一个比较小型服务,比如计算A+B的结果,那么我只要SVN和一个tomcat加上一个IDE就足够了,什么Spring,什么Struct都不需要。30KB+tomcat大小足以

Example 4:

我对外声称提供越来越多的服务,这时候可以用上DevOps的思想,节省部署的时间和复杂度

结论:

在没有提供使用场景和生命周期的情况下,说一个通用的项目应该具备哪些条件就是耍流氓。

在一般意义上,够用就好就足够了

Java性能调优.gc收集器的选择

需要关注

响应时间,吞吐量

最古典的Serial收集器在内存占用少于100MB的应用表现最好。

并行的Serial收集器在多核情况下能极大改善吞吐量,但是STW时间比较长

CMS同样在多核情况下表现好,但相比并行Serial收集器则吞吐量有下降但能极大的改善响应时间

包括新的G1收集器在内都无法解决不可控的STW时间

故而最近还有一种提议无收集器JVM,但是这样完全放弃了java的优势

还有一种java实时应用程序,用确定的STW时间来消除不可控的STW,但是极大地降低了吞吐量,且要在代码上作出一定的设计,否则程序无法顺利运行

总结:

Java的性能调优就是一场Trade off的行为

翻转单链表

package com.liangyumingblog;

public class LinkList
{
    private class Node
    {
        int value;

        Node next;

        public Node(int value, Node next)
        {
            this.value = value;
            this.next = next;
        }
    }

    private Node head = new Node(-1, null);

    private int size = 0;

    public void add(int value)
    {
        size++;
        Node current = head;
        while (current.next != null)
        {
            current = current.next;
        }
        current.next = new Node(value, null);
    }

    public Node getLast()
    {
        Node current = head;
        while (current.next != null)
        {
            current = current.next;
        }
        return current;
    }

    public Node removeLast()
    {
        Node current = head;
        while (current.next.next != null)
        {
            current = current.next;
        }
        Node tmp = current.next;
        current.next = null;
        tmp.next = null;
        return tmp;
    }

    public void reverse()
    {
        int length = 0;
        while (length != size)
        {
            insert(length, removeLast());
            length++;
        }
    }

    public boolean insert(int index, Node node)
    {
        if (index > size)
        {
            return false;
        }
        int now = 0;
        Node current = head;
        while (now != index)
        {
            ++now;
            current = current.next;
        }
        Node tmp = current.next;
        current.next = node;
        node.next = tmp;
        return true;
    }

    @Override
    public String toString()
    {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("[");
        Node current = head;
        while (current.next != null)
        {
            if (head != current)
            {
                stringBuffer.append(current.value);
                stringBuffer.append(", ");
            }
            current = current.next;
        }
        stringBuffer.append(current.value);
        stringBuffer.append("]");
        return stringBuffer.toString();
    }
}

 

趁着还没睡着,记一个今天学到的小小的分页trick

(totalrow+singlePageSize-1 )/singlePageSize

为什么说是个小trick呢

直观上我们做分页算法应该是这样的

return totalSize%singlePageSize!=0?totalSize/singlePageSize+1:totalSize/singlePageSize;

但是呢,最开始提到的算法,如果total/single有余数,由于int的直接截取的性质,所以totalrow/singlePageSize是向下取整了,但是这个余数加上(singlePageSize-1)再去除singlePagesize就刚好能够+1

否则因为(singePageSize-1)/SinglePageSize向下取整的性质,就变成了+0。所以说这里这个小Trick我还真没想到过,很巧妙

单点登录要素

单点登录的要素

中央认证服务器:用于生成ticket
应用服务器:要约定一个页面用于接收ticket,并写入相同域名内的cookie

技术上要解决

生成ticket的机制
ticket的失效机制

需要权衡的

每次验证ticket都需要到中央服务器认证:增加内部流量
通过租约:会有失效时间,不能保证马上所有位置都失效
中央服务器push到业务端通知失效:中央服务器压力大

Sort

基本的冒泡(O(n^2)):

public static void bubbleSort(int[] arrays, int begin, int end)
    {
        assert arrays != null;
        for (int i = begin; i < end; i++)
        {
            for (int j = begin; j < end; j++)
            {
                if (arrays[i] > arrays[j])
                {
                    swap(arrays, i, j);
                }
            }
        }
    }

    private static void swap(int[] arrays, int a, int b)
    {
        int t = arrays[a];
        arrays[a] = arrays[b];
        arrays[b] = t;
    }

继续阅读“Sort”