Friday, May 13, 2016

Ubuntu how to config JAVA_HOME

1.  Ubuntu how to config JAVA_HOME

To set JAVA_HOME environment variable, do the following:

Launch Terminal by pressing Ctrl+Alt+T on your keyboard.
Enter the following command:
$ gksudo gedit /etc/environment
Depending on where you installed your Java, you will need to provide the full path. For this example, I installed Oracle JDK 7 in the /usr/lib/jvm/java-7-oracle directory.
Scroll to the end of the file and enter the following:
JAVA_HOME=/usr/lib/jvm/java-7-oracle
export JAVA_HOME
Save your file and exit gedit.
Lastly, reload the system PATH with the following command:
$ . /etc/environment

http://askubuntu.com/questions/175514/how-to-set-java-home-for-java

Thursday, May 12, 2016

Java运行时如何开辟内存空间的?

为什么会出现OOM?
你了解JVM是如何分配内存空间的吗?
Static 是如何进驻内存的?
JVM对方法区的大小有限制吗?
对于堆和栈,除了是保存对象和引用,JVM 对于他们有限制吗?
java  静态方法存放在哪里?

你考虑过上面的问题吗?


JVM运行时数据区分类

程序计数器 (Program Counter (PC) Register)
JVM栈 (Java Virtual Machine Stacks)
堆内存 (Heap Memory)
方法区 (Method Area)
运行时常量池 (Run-time Constant Pool)
本地方法栈 (Native Method Stacks)


有图有真相:


按线程持有划分

查看上面的图,可以得知以上六个数据区其实线程私有还是共享,可以分为如下两种。

单个线程私有(Managed Per-Thread) 属于这一种的数据区包含 程序计数器, JVM栈还有本地方法栈。 每个线程都私有这三个数据区,这些数据区在其所属的线程创建时初始化,并随着所属线程结束被销毁。

多个线程共享 属于这一种的数据区包含 堆内存,方法区和运行时常量池。这些数据区可以被每一个线程访问,他们随着JVM启动而初始化,同时伴随JVM关闭而销毁。
程序计数器

在通用的计算机体系中,程序计数器用来记录当前正在执行的指令,在JVM中也是如此。程序计数器是线程私有,所以当一个新的线程创建时,程序计数器也会创建。由于Java是支持多线程,Java中的程序计数器用来记录当前线程中正在执行的指令。如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined。注意这个区域是唯一一个不抛出OutOfMemoryError的运行时数据区。

JVM栈

在介绍JVM栈之前,简单介绍一个概念,栈帧

栈帧

一个栈帧随着一个方法的调用开始而创建,这个方法调用完成而销毁。栈帧内存放者方法中的局部变量,操作数栈等数据。

JVM栈只对栈帧进行存储,压栈和出栈操作。栈内存的大小可以有两种设置,固定值和根据线程需要动态增长。在JVM栈这个数据区可能会发生抛出两种错误。

StackOverflowError 出现在栈内存设置成固定值的时候,当程序执行需要的栈内存超过设定的固定值会抛出这个错误。
OutOfMemoryError 出现在栈内存设置成动态增长的时候,当JVM尝试申请的内存大小超过了其可用内存时会抛出这个错误。

堆数据区

堆数据区是用来存放对象和数组(特殊的对象)。堆内存由多个线程共享。堆内存随着JVM启动而创建。众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。

方法区

在JVM规范中,方法区被视为堆内存的一个逻辑部分。这一点可能由于具体的JVM实现而不同,甚至在方法区不实现垃圾回收处理也是可以的。方法区和堆内存一样被多个线程访问,方法区中存放类的信息,比如类加载器引用,属性,方法代码和构造方法和常量等。当方法区的可用内存无法满足内存分配需求时,JVM会抛出OutOfMemoryError错误。

运行时常量池

运行时常量池创建在方法区,当一个类或者一个接口被创建的时候,JVM会创建一个运行时常量池。一个运行时常量池实际上是一个类或者接口的class文件中常量池表(constant_pool table)的运行时展示形式。一个运行时常量池包含了多种类型的常量,从诸如运行时可以确定的数值型字面量到运行时才能决定的方法和属性引用。当运行时常量池无法满足于内存分配需求时,JVM会抛出OutOfMemoryError错误。

本地方法栈

一个支持native方法调用的JVM实现,需要有这样一个数据区,就是本地方法栈,Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。一个不支持本地方法执行的JVM没有必要实现这个数据区域。本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误。


=======================

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。


堆  主要是用来存储对象的
栈  主要是用来执行程序的





Thanks to:






Wednesday, May 11, 2016

How to use git delete remote branch?



you can use this command:

git push origin --delete  branchName





Thanks to:

Ubuntu Android sutdio works for me

Today, Finally I finish Android sutdio can run the peogram for my app!

Now, I can coding in my Ubuntu Evronment!

Thanks for myself!

Gradle自定义你的BuildConfig


http://stormzhang.com/android/2015/01/25/gradle-build-field/


在很早之前我发布了这篇博客Android BuildConfig.DEBUG的妙用, 提到了Eclipse中通过BuildConfig.DEBUG字段用来调试Log非常好用,但是殊不知在Android Studio中通过Gradle这种用法更加强大。

BuildConfig.DEBUG

首先在Gradle脚本中默认的debug和release两种模式BuildCondig.DEBUG字段分别为true和false,而且不可更改。该字段编译后自动生成,在Studio中生成的目录在 app/build/source/BuildConfig/Build Varients/package name/BuildConfig 文件下。我们以9GAG为例来看下release模式下该文件的内容:
public final class BuildConfig {
  public static final boolean DEBUG = false;
  public static final String APPLICATION_ID = "com.storm.9gag";
  public static final String BUILD_TYPE = "release";
  public static final String FLAVOR = "wandoujia";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
  // Fields from build type: release
  public static final boolean LOG_DEBUG = false;
}

自定义BuildConfig字段

大家看到上述内容的时候发现莫名的有个LOG_DEBUG字段,这个完全是我自定义的一个字段,我来用它控制Log的输出,而没有选择用默认的DEBUG字段。举例一个场景,我们在App开发用到的api环境假设可能会有测试、正式环境,我们不可能所有的控制都通过DEBUG字段来控制,而且有时候环境复杂可能还会有两个以上的环境,这个时候就用到了Gradle提供了自定义BuildConfig字段,我们在程序中通过这个字段就可以配置我们不同的开发环境。
语法很简单:
buildConfigField "boolean", "API_ENV", "true"
上述语法就定义了一个boolean类型的API_ENV字段,值为true,之后我们就可以在程序中使用BuildConfig.API_ENV字段来判断我们所处的api环境。例如:
public class BooheeClient {
    public static final boolean DEBUG = BuildConfig.API_ENV;

    public static String getHost {
        if (DEBUG) {
            return "your qa host";
        }
        return "your production host";
    }
}
不仅如此,如果遇到复杂的环境,你也可能自定义一个String类型的字段,这种方式免去了发布之前手动更改环境的麻烦,减少出错的可能性,只需要在Gradle配置好debug、release等模式下的环境就好了,打包的之后毫无顾虑。

代码重构的感悟

随着自己的能力的不断的增长,主要是自己的视野和格局在不断的增长。让自己,觉的现在的代码越来越垃圾了,急需重构代码。项目中的冗余代码越来越多,这是为什么呢?这是因为,之前开发规范的问题。没有一个很好的规范,导致了各种问题,当然也埋下了很多的坑!

这么说,一个六个人的团队,未必就会比一个人的做的好!因为,In China 很多的时候,我们往往只相信自己的能力,并不相信别人。总觉的被人是傻逼。一般的只要不是大公司,小公司也包括中型的公司,新人到了公司之后,缺少代码规范的训练。因为,似乎每个人都很忙,他们不知道,现在的很忙,导致了以后会更忙。新人,必须要代码规范。但是,很多初级的程序员,往往没有这种意识!需要我们来督促!

说说,今天! 今天上午发了包,下午有点自己的时间,可以让自己来重构自己的代码!说真的我很庆幸现在自己的状态,因为,我算是 天时  地利  人和。 我很是庆幸,比如我的哥们,小强,他作为一个新人刚到公司,看到公司垃圾的代码,但是,他不可以重构,因为,作为新人,到了公司没有什么话语权。这个社会就是这个样子的,新人要有新人的样子。就像PM 很多都是傻逼,娜姐除外。说白了,很多人根本就是看不起程序员,我们一般是比较理想化的人,活在自己的世界里面,感觉自己的世界里面,自己似乎可以做所有的事情!说白了,我就是自己的神。总之,我现在重构我的代码,没有意思的顾虑,就是只要自己有时间就好了!花点精力来做这件事情。我觉的代码就像自己的老婆一样,如果,你都不花心思来整理,还有谁会对你的代码上心呢?所以,代码可以变的更好,实现 可修改,可维护,可增量!

这个世界上的事情,需求是不断的改变的。假如 需求是死的,那么的你活着还有什么意思!
我们就生活在不断变化 的世界里面

下面说说我的重构代码的感悟:

1 命名规范
这个问题,真是很蛋疼呢?说白了,很多人写代码就是瞎鸡巴写,根本就不在谁来维护代码,只要代码实现了就好,什么有道词典,百度呀,google 翻译呀,瞎鸡巴乱搞,很快他们就实现了功能,老板很开心,因为,很快就看到了产品,在老板的心里面,产品的代码应该是整整齐齐的。但是,在程序猿的心里面代码是乱七八糟的,我说的是大多数的。作为,刚到公司的人急于表现自己的能力,想让自己的能力得到老板的肯定。然后,就瞎鸡巴揽活,拿到需求之后,看到产品原型图,就瞎鸡巴写,写了之后发现有问题,就开始瞎鸡巴改!真是蛋疼的狠!最后,发现 坑越来越多,自己的坑越来越多,这是一个量变促进质变的过程。到了最后,发现自己真的是改不动bug了!然后,递交了辞职信!   这尼玛就是坑货, 新来的人  又开始了死循环!

解决:
命名规范的问题,每种语言都有自己的特性,但是命名确实大同小异。你需要根据自己的习惯总结一套自己的命名规范。不是每个人都有这种意识,很庆幸,我有这种意识!这个东西,CTO 产品经理 可以制订一份文档,来规范用到的英文。没有在文档汇总的,程序员可以  google,添加到文档中!

命名的规范有很多,我就不介绍了,你们随便找找吧!

2  Utils
为什么要提取Utils
今天,我的项目中用到了ImageLoader.  DisPalyOptions 很多地方都初始化了,将近 100 多个地方都用自己重新定义了一下!这样的重复代码, 根本原因,我们开发的时候,很多的时候只会粘贴复制。粘贴复制到了 代码的重复!

我的原则:  重复的地方超过了3次以上,立马听一下工作开始重构代码,或者提取到工具类!

我这里建立 了一个ImageLoaderUtils, 来处理 不同的DisplayOptions,  displayImage(). 

但是,这么做有什么好处呢?

我有一个问题,加入有一天,我不想用ImageLoader了,我想换一种 图片加载工具,比如 Passco 实现图片的加载。但是,现在的代码修改起来,代价太大了。因为内部代码跟ImageLoader 的耦合度太大了,属于低内聚,高耦合。就是,所有用到ImageLoader的地方都要修改。这样很不好。

这个时候,我体会到了解释器设计模式的用处。

提取工具类是一个非常好的习惯。因为,可以消重。消除重复代码的原则:拆分和抽取。就是 大事化小,小事化了,了事化无。

用了ImageLoaderUtils 之后,我可以在这个累的基础之上去使用适配器模式,做不同的  图片加载工具的 adapter. 我只需要链接不同的 图片加载的特性。然后,抽取一个 BaseImageLodaerUtil 设置几个抽象的方法,然后,让子类实现以下,就可以了!具体的需要思考。


这就是我今天的收获!


















Tuesday, May 10, 2016

WIndows 三大法宝

windows    三大法宝  重启 重装软件   重装系统