拓展性

假设我们有一张用户表:

uid,username,nickname,birthday……等有限个元素

当我们需要加入用户更多的信息应该如何实现?

有如下两个我想到的方案

  1. 根据uid作为外键,然后建立新表
  2. 在此表中加入一个可以动态扩展的字段

先说第一种,

比如我要新加一种属性,叫用户性别:gender;那么我就可以新建立一张表叫做gender,或者直接用db的外键,或者直接带逻辑代码中用uid查询。

这里的好处是可以保持原来的字段不改变,避免原来的表结构膨胀,可以直接做索引(扩展字段无法索引,随时可能超出64字节的索引量,MYSQL)

第二种,

我们可以在用户表中新增一个null的字段,叫做ext,中间保存的是json字符串,这个字符串由各个业务共同使用各自转换成相应语言中的数据结构

好处也是不增加新表

坏处是这个字段是无法索引的,所以只能存放一些静态的,不需要索引的数据

离职的蛋疼

三月十号提的离职,

接下来两周各种交接工作,第三周开始就开始无聊了。。。

说起来忙的时候反而更愿意学习,闲下来了反而不愿意,宁愿在网上瞎点。

包括连三月初我非常感兴趣的JVM的研究,Windows有时候真的对程序员不友好,起码各种工具的exe没有完整的注册自己,跟着一些教程走简直就是给自己挖坑。

蹲在公司有一点坏处,写的代码不能传网上,包括自己写的,这就很蛋疼了。而且不参与开发的话,就不会产生出一些idea

不过这一周准备过完了,马上就是放假了,期待新入职的公司能够得到一些我没见过的视野。

编程珠玑|读书笔记

  • 给定40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的整数

首先先估算大小:

一个32位整数4bytes

40亿则是4*4.000.000.000bytes = 15625000KB ~= 15258MB ~= 15GB

如果采用bitmap还可以降低为2GB左右的内存

显然,现在随便一台高级点的计算机可以达到此内存级别,那么内存充足的情况下,直接对这个文件做map,然后顺序遍历一遍,空间复杂度为O(n),时间复杂度为O(n)

在内存不足情况下,但是有额外的外存空间,我们做归并排序,然后遍历,时间复杂度为O(n+nlogn)

还有一种做法是标准的二分查找:

我们给定一个分割标准(这里用整数的范围做标准),使得40亿个整数能够均匀的分布在两个文件

然后找到哪部分的文件不够20亿个,重复上一步骤直到整数范围上限和下限相同,则此时上限=下限=缺失的文件

  • 给定一个英语词典,找出其中所有变位词集合

我们为每一个英文字母映射成一个素数,遍历字典,找出英文字母对应的素数乘积值一样的,即是变位词。

这个正确性由算术基本定理保证

‘好’得边界

昨晚写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();
    }
}