学了Java 你未必知道这些

    做为一个正奔跑向编程完美天堂的朝圣者,本人以为在日常的编程中,应该要作到如下几点:算法

    一:汝应注释,这样作既方便别人,也方便本身去读懂代码的逻辑数据库

    二:注重细节,为本身写的每行代码负责,好比,在并发编程的过程当中,应该给那些可变的共享单元加“同步锁”或把可变的共享变量的粒度降到每一个线程的级别编程

    三:注重效率,因为本人的学校比较重视算法这一块,因而不知不觉中就对程序执行效率这一块比较执着,假如你和你的同事们都写了一个相同功能的程序,而后老板给大家                  各100万条数据,你的同事的程序很快就把这100万条数据执行完了,而后去喝了杯咖啡,回来时若是你的代码还在跑,这不是......(后面的话大家都懂的)安全

    四:注重代码的整洁性和尽力让代码的冗余降到最低,这在代码的重构上是要注意的地方。性能优化

  后续本人会写一些本人读到的比较好的算法例子,读这些例子有利于咱们思惟活跃开来,固然,相信你也会像本人同样为这些算法解法的巧妙性而啧啧称奇,以至使本身在之后的编程中更加注重这一块,这些例子你们之后能够查看这个网址 http://www.cnblogs.com/wanggangjia/来看看(后续会补上这些算法序列)
  好吧!前菜已了,正餐如今来了并发

      1.请你完善下列函数来实现这个功能:交换下面例子中A、B的值 函数

1 public class TestAdd {
2     public static void main(String[] args) {
3            int A = 100;
4            int B = 10;
5            .....   //在这里写下你的代码,使A,B的值交换
6            System.out.println("A:" + A + "\t" + "B:" + B);  //输出  A:10   B:100
7 }  
8 
9 }

    (1)大多数的咱们都会定义一个临时变量temp,而后就以下面代码同样性能

int temp = A;
A = B;
B = temp;

    (2)又有人会说,定义一个变量多奢侈啊!看个人学习

A = A + B;
B = A - B;
A = A - B;

    (3)这确实比(1)解法好了一点,但咱们知道系统处理数据最快的是位操做,咱们能不能从这方面下手使咱们的程序更快呢?并且,把A+B赋值给A可能会产生越界,这不是不安全吗?那怎么办才能兼顾安全、快速、简洁呢?看码以下(采用“异或”操做符):优化

A = A ^ B;
B = A ^ B;
A = A ^ B;

说明:异或运算是按照二进制位进行异或运算的,这个运算是最低级的CPU位运算,运行速度快,并且不会产生进位。

拓展:位操做符因为它们具备运行速度快的特色(思考一下它们快的缘由),因此常常被使用,特别是“>>”或“<<”位运算符,这点读者能够看看jdk中有关hashcode这一块的源码

拓展例子:编程实现2 * 8,直接给码以下:

2<<3;  //假设每一个变量的存储是8位,则2的二进制是0000 0010,向左偏移3位后,可得0001 0000,转换成十进制为16,不就是2 * 8,数3是由于2的3次方为8

  2.这条语句:float i = 3.3;能编译经过吗?

float i = 3.3;不能经过编译,由于常数 3.3 Java默认是double类型,而float类型的范围是比double小的,把3.3赋值给i 是向下转型,会损失精度,若是真的须要赋值给i,需强制转型float i = (float)3.3;

拓展:short i = 1,i = i + 1;这也是不能经过编译的,由于Java默认常数1位int类型,理由同上,可是short i = 1,i += 1;倒是能够的,这是由于jdk在编译的时候,会隐式的将类型强制转换成i = (short)(i + 1);

  3.Java中int类型和Integer类型有什么区别?

 首先,int类型是Java的基本数据类型,而Integer是一个对象,是一个引用,它们在内存逻辑就不一样,关于内存逻辑,能够看看本人所写的“一个大三学生的学习之悟”这篇文章,下面给出这两个类型的内存结构,既然Integer是一个对象,那么它相对于int这基本类型来讲就有不少额外的方法,具体可自查Java的API,要特别说明的是:在jdk1.5引入了“自动拆箱和装箱”,使得基本数据类型和其对应的封装对象可以隐式的转换。

综合例子:涵盖的知识点包括自动装箱和拆箱、内存结构分析、自动装箱和拆箱背后的相似“对象池”的思想

 1 public class BoxingTest {
 2     public static void main(String[] args) {
 3           Integer i = new Integer(300);
 4           Integer j = 300;  //自动装箱,内部机制是调用Integer的valueOf(int)方法
 5           int z = 300;
 6           System.out.println(i == j);  //false  由于它们的内存地址不一样
 7           System.out.println(z == j); //true  由于j自动拆箱,内部机制是调用Integer的intValue()方法,它们比较的都是数值300
 8     }
 9 
10 }

读到这里,若是你没有一种去读Integer的valueOf(int)方法的源码的冲动,那么你将失去挺多东西的,由于它里面包含着Java在性能优化的一些蛛丝马迹,算了,我仍是讲讲吧!若是你没有去看这个方法的源码,相信把下面这道题彻底作对的应该不太可能,先炫代码:

 1 public class ValueOfTest {   //使用驼峰形式命名
 2 
 3       public static void main(String[] args) {
 4              Integer i = 50;
 5              Integer j = 50;
 6              Integer x = 200;
 7              Integer y = 200;
 8            
 9              System.out.println(i == j);  //true
10              System.out.println(x == y); //false
11        }
12 
13 }

分析以下:

1  public static Integer valueOf(int i) {   //注意这里是静态方法,隶属于类,因此能够直接使用 “Integer.方法名” 来调用该方法
2  
3          if (i >= IntegerCache.low && i <= IntegerCache.high)  //这里的IntegerCache.low默认值为-128   IntegerCache.high默认值为127
4              return IntegerCache.cache[i + (-IntegerCache.low)];  //这些Integer对象,默认范围在[-128~127],已经被建立,被放在常量池里
5  
6          return new Integer(i);
7 
8     }

 

因为Java的操做不外乎是建立对象---使用对象----销毁(回收)对象,由于建立对象比较耗时间,损失了系统的性能,因此咱们通常都会在程序开始时对一些比较耗时但在咱们的程序又常用的对象先会初始化一些实例,对象池的对象是如此,线程池的线程是如此,数据库链接池的Connection对象也是如此,供咱们在程序中调用,以达到对象的重用及快速引用,这是优化程序功能的一个方法。好吧!回归本题,范围在[-128~127]的Integer对象已经被初始化在常量池里了,因此在这区间的Integer对象建立时都会指向常量池中相对应的对象,这也是上面代码中为何第一个输出为true的缘由,在这个范围以外的,它会本身建立一个Integer对象,因此根据内存逻辑可知它们并不相等,因此为false

  其实,有空读读Java源代码也是有好处的,在这里,本人只是但愿编程者们在日常的代码编辑中,要时刻注重本身程序的安全性、代码运行的效率性及项目的性能的优化等等

相关文章
相关标签/搜索