面试宝典6-12题

▼魔方 西西 提交于 2019-12-22 00:38:48

6、short s1 = 1;s1= s1+1;有什么错?short s1=1;s1+=1;有什么错?

答:首先要知道,数据类型之间的转换模式:大转小需要强制转换,小转大可以直接转换。前者,编译器会报错,因为在java的默认整数类型是int,s1+1中s1是short类型****1是默认的int整数类型,相加的结果是int类型(会被编译器隐式转换),用int类型的值赋值给short需要强制类型转换才可以。后者是由于在执行完s1+1运算之后会强制转换成+=符号前面的表达式的类型 ,所以就不会出错了。总结一句话就是s1+=1比s1=s1+1多了一步强制转换的过程.

7、char型变量中能不能存储一个中文汉字?为什么?

答:可以的。因为char类型被设计出来用于存放Unicode编码的,而Unicode编码字符中包含了汉字(不包括特殊汉字),所以char型变量是可以储存一个汉字的
代码演示:

public class Deno {
	public static void main(String[] args) {
		char s = '中';//定义char型变量中
		System.out.println(s);
		char a='\u4e2d';//定义Unicode编码,此编码对应中文汉字  中
		System.out.println(a);
	}
}

输出结果

中
中

8、如何用最有效的方法算出2乘以8等于几?

答:可以使用向左位移的方式将2向左位移3,因为将2向左位移3就相当于2乘以2的3次方,2的3次方为8。
测试代码:

public class Deno {
	public static void main(String[] args) {
		int c=2*8;
		int a=2;
		System.out.println(a<<3);
		System.out.println(c);
	}
}

输出结果如下:

16
16

9、请设计一个百亿计算器

答:回答此题前首相想到要用一个容器存储,而能存储百亿数值的有 int,long,double,为了更好地节省内存,我取用int类型来做此题。
代码如下:
来源:https://blog.csdn.net/wilsonpeng3/article/details/22441009
Deno.java

package test;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Rocky on 14-3-26.
 */
public class Deno {
	private char sign = '0'; // 0 表示正数 - 表示负数
	private byte[] data;

	public Deno() {
		this.data = "0".getBytes();
	}

	public Deno(String value) throws Exception {
		// 正则表达式,输入字符串要求以 零个或一个 - 开头,其余都是数字
		Pattern pattern = Pattern.compile("^-?\\d+$");

		if (value == null || value.length() <= 0) {
			value = "0";
		}
		Matcher matcher = pattern.matcher(value);
		if (!matcher.find()) {
			throw new Exception("the value is not a number string :" + value);
		}
		// 获取字符串的第一个字符
		char firstChar = value.charAt(0);

		// data应该保存的是第一个非0数字后的字符串
		if (firstChar == '-') { // 说明输入的是个负数
			if (value.length() >= 2) {
				sign = firstChar;
				value = value.substring(1);
				value = getTemp(value); // 得到value中第一个非0后的子字符串。
			}
		} else {
			value = getTemp(value);
		}
		this.data = value.getBytes();
	}

	/**
	 * 得到一个字符串第一个非0后的字符串,如果没有找到,则返回 "0" 。如:00003435534,则返回3435534
	 * 
	 * @return
	 */
	private String getTemp(String value) {
		Pattern pattern = Pattern.compile("[^0]{1}");
		Matcher matcher = pattern.matcher(value);
		if (matcher.find()) {
			value = value.substring(matcher.start());
		} else {
			value = "0";
		}
		return value;
	}

	public Deno add(Deno other) {
		Deno result = new Deno();
		int thisLength = this.data.length;
		int otherLength = other.data.length;
		int shorterLength = thisLength > otherLength ? otherLength : thisLength;
		ArrayList<Byte> resultData = new ArrayList<Byte>();
		int flag = 0; // 表示相加时的 进位,或相减时的 借位
		int i = thisLength - 1;
		int j = otherLength - 1;
		int k = shorterLength;

		// 两个数的符号相同
		if (other.sign == this.sign) {
			// 从两个整数的个位开始依次相加
			while (k > 0) {
				Integer temp = new Integer(new String(
						new byte[] { this.data[i] }))
						+ new Integer(new String(new byte[] { other.data[j] }))
						+ flag;
				flag = temp / 10; // 相加结果超过10时的进位。没有超过10,进位为 0
				resultData.add(0, ((temp % 10) + "").getBytes()[0]); // 把相加结果保存起来
				k--;
				i--;
				j--;
			}
			// 把多出的位加入到结果中
			if (i == -1) {
				while (j >= 0) {
					Integer temp = new Integer(new String(
							new byte[] { other.data[j] }))
							+ flag;
					flag = temp / 10;
					resultData.add(0, ((temp % 10) + "").getBytes()[0]);
					j--;
				}
			} else if (j == -1) {
				while (i >= 0) {
					Integer temp = new Integer(new String(
							new byte[] { this.data[i] }))
							+ flag;
					flag = temp / 10;
					resultData.add(0, ((temp % 10) + "").getBytes()[0]);
					i--;
				}
			}
			// 最后把flag加进结果中
			if (flag != 0) {
				for (byte by : (flag + "").getBytes()) {
					resultData.add(0, by);
				}
			}
			result.sign = other.sign;
		} else { // 符号不同
			if (thisLength > otherLength) { // 说明this表示的整数绝对值大,所以最终结果的符号为this的符号
				result.sign = this.sign;
				resultData = subtract(this.data, other.data); // 执行减法
			} else if (thisLength < otherLength) { // other表示的整数绝对值大,所以最终结果的符号为other的符号
				result.sign = other.sign;
				resultData = subtract(other.data, this.data);
			} else { // 如果两个数据的位数相同
				Integer thisInt = 0;
				Integer otherInt = 0;
				// 从第一位开始比较,直到两者不相等
				for (int n = 0; n < thisLength; n++) {
					thisInt = new Integer(new String(
							new byte[] { this.data[n] }));
					otherInt = new Integer(new String(
							new byte[] { other.data[n] }));
					if (!thisInt.equals(otherInt)) { // 注意这里要使用equals方法,因为这里需要比较的是两者的内容
						break;
					}
				}

				// 如果this的绝对值大
				if (thisInt > otherInt) {
					result.sign = this.sign;
					resultData = subtract(this.data, other.data);
				} else {
					result.sign = other.sign;
					resultData = subtract(other.data, this.data);
				}
			}
		}
		result.data = new byte[resultData.size()];
		for (int m = 0; m < resultData.size(); m++) {
			result.data[m] = resultData.get(m);
		}
		return result;
	}

	private ArrayList<Byte> subtract(byte[] larger, byte[] smaller) {
		ArrayList<Byte> resultData = new ArrayList<Byte>();
		int flag = 0;
		int i = smaller.length - 1;
		int j = larger.length - 1;
		int k = smaller.length;
		while (k > 0) {
			Integer temp = new Integer(new String(new byte[] { larger[j] }))
					+ flag - new Integer(new String(new byte[] { smaller[i] }));
			if (temp < 0) { // 如果相减结果小于0,说明需要借位,则把flag置为 -1,以便下一位减去
				flag = -1;
				temp += 10;
			} else { // 如果大于零,需要把flag置为 0.不要忘记了
				flag = 0;
			}
			resultData.add(0, (temp + "").getBytes()[0]);
			j--;
			i--;
			k--;
		}
		// 下面的代码就不写注释了
		while (j >= 0) {
			Integer temp = new Integer(new String(new byte[] { larger[j] }))
					+ flag;
			if (temp < 0) {
				flag = -1;
				temp += 10;
			} else {
				flag = 0;
			}
			resultData.add(0, (temp + "").getBytes()[0]);
			j--;
		}
		return resultData;
	}

	@Override
	public String toString() {
		String str = new String(this.data);
		str = getTemp(str);
		if (sign == '-' && str != "0") {
			str = sign + str;
		}
		return str;
	}

}

TestDeno.java

package test;

import test.Deno;
import java.math.BigInteger;
 
/**
 * Created by Rocky on 14-3-26.
 */
public class TestDeno extends Deno {
    public void test1() throws Exception {
        String a1 = "-5453450543044355356576980545345054545453453454344435353254545345054304435535657698087756454543454345454534534543444353532545453450543044355356454543454354353450136546534534545345345054353450136546534534545345345043044355356576980657698087756454543454354353450136546534534545345345054353450136546534534545345345043044355356576980877564545434543543534501877564545434543543534501";
        String b1 = "4545453453454344435353254545345054304435535657698087756454543454354345454534534543444353532545453450543044355356576980877564545434545454534534564545434543543534501365465345345453453450543534501365465345345453453450430443553565769804344435353254545345054304435535657698087756454543454354353450136546534534545345345043543534501365465345345453453450534501365465345345453453450";
        Deno a = new Deno(a1);
       Deno b = new Deno(b1);
        Deno c = a.add(b);
        System.out.println(c);
        BigInteger a2 = new BigInteger(a1);
        BigInteger b2 = new BigInteger(b1);
        BigInteger c2 = a2.add(b2);
        System.out.println(c2);
        System.out.println(c2.toString().equals(c.toString()));
    }
}

输出结果:
在这里插入图片描述

10、使用final关键字修饰一个变量时,是引用不能变,还是引用对象不能变?

答:引用变量不能变,引用对象可以变通过代码测试如下:

package test;

/**
 * @长青子 2019-12-21.
 */
public class Deno {
	public static void main(String[] args) {
		final StringBuffer a = new StringBuffer("你好!");
		// a = new StringBuffer(""); 编译错误,因为final修饰的引用类型变量,引用对象地址不可改变
		a.append("Hello"); // 编译通过,final修饰的引用类型变量,所引用的对象的值可以改变
		Test(a);
		System.out.println(a);
	}

	// 如果在定义方法参数时希望方法内部不能修改此参数的值,这样做是无效的,理由同上
	public static void Test(final StringBuffer a) {
		a.append("Java");
	}

}

输出结果如下:

你好!HelloJava

11、“==”和equals方法究竟有什么区别?

答: ==操作符用来比较两个值是否指向同一地址,而equals则是比较两个独立对象的内容是否相同,用下面代码来区分它们的区别:

package test;

/**
 * @长青子 2019-12-21.
 */
public class Deno {
	public static void main(String[] args) {
		String a="你好";
		String c=new String("你好");
		System.out.println(a==c);//比较两个地址是否相同 
		System.out.println(c.equals(a));//比较两个内容是否相同
		
	}
}

结果:

false
true

12、静态变量和实例变量的区别?

答:在回答之前,先看看它们俩的区别:
静态变量:被static修饰的成员变量叫做静态变量,也叫做类变量,说明这个变量是属于这个类的。可以通过类名可以直接调用。
实例变量:没有被static修饰的成员变量叫做实例变量,说明这个变量是属于某个具体的对象的。必须创建对象才能使用对象来使用。
代码演示:

package test;

/**
 * @长青子 2019-12-21.
 */
public class Deno {
		String name;// 成员变量,实例变量。随着对象的创建而存在于堆内存中
		static String country = "CN";// 静态的成员变量,类变量。随着类的加载而存在于方法区中

		public static void show() {
			System.out.println("::::");
			// this.haha();//静态方法中不能出现this关键字
		}

		public void haha() {
			System.out.println("hahaha...");
		}

	public static void main(String[] args) {
			Deno p = new Deno();
			p.haha(); // 对象调用成员方法
			Deno.show();// 类名调用静态方法,也可对象调用静态方法(不推荐)
	}
}

输出结果:

hahaha...
::::
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!