数组基地址运算
/*
数组A=array[1..100,1..100]以行序为主序存储
设每个数据元素占2个存储单元
基地址为10,则LOC[5,5]应为
正确答案: C
1020
1010
818
808
还是需要用上公式
Loc(1,1) + [n * (i - 1) + j - 1] * b
代入数得
10 + [100 * (5 - 1) + 5 - 1] * 2 = 818
*/
子串和子序列
/*
字符串"www.qq.com"所有非空子串
(两个子串如果内容相同则只算一个)个数是
正确答案: D
1024
1018
55
50
这里补充2个概念
(非空)子串
从左到右一次截取
10个字符的子串1个
9个字符的子串2个
8个字符的子串3个
... ...
然后减去重复的子串
1个字符的子串中
3个w
2个q
2个.
2个字符的子串中
2个ww
所以需要删除
(2 + 1 + 1 + 1) = 5
所以最终的结果是
1 + 2 + ... + 10 - 5 = 50
子序列
2**n
n表示双引号中一共有多少个字符
这里2**10 = 1024
*/
bug日志记录
/*
idea错误日志报告
java.lang.AssertionError: Unexpected content storage modification: page=18; newRecord=491
翻译过来是
断言错误,未预期的内容存储
stackoverflow中的国外码友给出了解决方案
If you cannot even open your project in IntelliJ:
Close IntelliJ
Go to the directory <your_home>/.IntelliJIdeaXX/system/cache
where XX is your IntelliJ version
Remove all the files in the cache directory.
Then restart IntelliJ
This has worked for me in the past.
翻译过来就是
如果你甚至不能在IntelliJ中打开你的项目。
关闭IntelliJ
进入目录<your_home>/.IntelliJIdeaXX/system/cache
其中XX是你的IntelliJ版本
移除缓存目录中的所有文件
然后重新启动IntelliJ
这在过去对我很有效
所以我就找到了用户文件夹下的.IntelliJIdeaXX/system/cache文件夹
删除了下面的所有文件
程序恢复正常运行
cache文件夹存放IDEA配置信息和缓存信息
随着使用时间越长,该文件夹越来越大
打开任务管理器
惊恐地发现IDEA对CPU占有率超过了80%
CPU不堪重负
删除完cache文件夹下的所有文件后
IDEA对CPU占有率恢复了正常的0.2%左右
很重要的发现,记录一下
*/
自动装箱和常量池
class Test13 {
public static void main(String[] args) {
Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);
System.out.println(i01 == i02); // true
System.out.println(i01 == i03); // true
System.out.println(i03 == i04); // false
System.out.println(i02 == i04); // true
}
/*
自动装箱变着花样考你
首先常量池这个概念
Byte,Short,Integer,Long,Character这5种整型的包装类
对应值小于等于127并且大于等于-128时可使用常量池
因为他们至占用一个字节(-128~127);
回到这道题
Integer是引用类型,int是基本类型。
i02 == i04时,i04自动拆箱
调用Integer的intValue()方法,返回是一个int类型
所以2和4比返回true
3和4比返回false
*/
}
双等号和equals方法的区别
class Test14 {
public static void main(String[] args) {
String s = "hello";
String t = "hello";
char c [ ] = {'h','e','l','l','o'};
System.out.println(s.equals(t)); // true
System.out.println(s.equals(c)); // false
System.out.println(t.equals(new String("hello"))); // true
/*
首先==与equals是有明显区别的。
==强调栈中的比较,可以理解为地址比较
equals强调对象的内容比较
String s=“hello”;
会在栈中生成hello字符串,并存入字符串常量池中
String t=“hello”;
创建时,会在字符串常量池中寻找
当找到需要的hello时,不进行字符串的创建,引用已有的
所以,s==t返回true,s.equals(t)也是true
char c[]={'h','e','l','l','o'}; c==s这个是不存在的,==两边类型不同
t.equals(c)这个语句在anObject instanceof String这步判断不会通过
也就是cha[] 压根不能与String相比较,类型不是相同的
返回false
对于"=="
* 用于基本数据类型相互比较. 比较二者的值是否相等.
* 用于引用数据类型相互比较. 比较二者地址是否相等.
* 不能用于基本数据类型与引用型比较.
对于"equals":
* 不能用于基本数据类型比较(因为这是一个方法, 继承自Object).
* 用于进行对象的比较, 比较二者的引用地址是否相同.
* 在此处String类重写了equals方法,比较的是内容
特殊情况:
* 数值型基本类型和数值型类会存在自动装箱和自动拆箱.
* 字符串会以常量形式存在, 如果多个字符串变量值相同, 则他们指向同一个地址.
* 数值类型会存在类型自动转换.
*/
}
}
继承中代码执行顺序
class Demo1 {
class Super {
int flag = 1;
Super() {
test();
}
void test() {
System.out.println("Super.test() flag=" + flag);
}
}
class Sub extends Super {
Sub(int i) {
flag = i;
System.out.println("Sub.Sub()flag=" + flag);
}
void test() {
System.out.println("Sub.test()flag=" + flag);
}
}
public static void main(String[] args) {
new Demo1().new Sub(5);
/*
在继承中代码的执行顺序为:
1.父类静态对象,父类静态代码块
2.子类静态对象,子类静态代码块
3.父类非静态对象,父类非静态代码块
4.父类构造函数
5.子类非静态对象,子类非静态代码块
6.子类构造函数
1.首先调用父类构造方法,即super()
2.调用test()方法
3.由于在子类sub()中重写了test()方法,所以调用子类test()
4.输出Sub.test() flag=1
5.调用sub的有参构造方法
6.输出Sub.Sub() flag=5
重点在于要时刻记得子类重写父类方法,调用时会调用子类重写之后的方法
当然,这一切的前提都是 实例化子类对象
new Demo1()的时候,父类先初始化int flag = 1
然后执行父类的构造函数Super(),
父类构造函数中执行的test()方法,
因子类是重写了test()方法的
因此父类构造函数中的test()方法实际执行的是子类的test()方法
所以输出为Sub.test() flag=1
此时父类已经初始化完成
接着执行子类构造函数Sub(5)
将flag赋值为5
因此输出结果Sub.Sub() flag=5
*/
}
}
子类重写父类方法
/*
将下列哪个代码A、B、C、D放入程序中标注 // add code here 处将导致编译错误
class A{
public float getNum(){
return 3.0f;
}
}
public class B extends A{
// add code here
}
正确答案: B
public float getNum(){return 4.0f}
public void getNum(){}
public void getNum(double d){}
public double getNum(float d){return 4.0d}
子类重写父类方法
要求
方法名,返回值类型,参数完全相同
所以A符合
B返回值类型不同,编译错误
而C和D不仅返回值类型不同,参数也不同
参数一旦不同,就彻底不是重写父类方法了
不属于方法重写,而是属于子类自己新增的方法
所以选B
*/
Java异常分类
/*
关于异常的编程,以下描述错误的是:
正确答案: A
在有除法存在的代码处,为了防止分母为零,必须抛出并捕获异常
int i=Integer.parseInt(”123a”);将产生NumberFormatException
int a[]=null; a[0]=1; 将产生NullPointerException
输入输出流编程中,读和写时都要抛出IOException
Java的异常分为两种,一种是运行时异常(RuntimeException)
一种是非运行异常也叫检查式异常(CheckedException)
1、运行时异常不需要程序员去处理,当异常出现时,JVM会帮助处理
常见的运行时异常有:
ClassCastException(类转换异常)
ClassNotFoundException
IndexOutOfBoundsException(数组越界异常)
NullPointerException(空指针异常)
ArrayStoreException(数组存储异常,即数组存储类型不一致)
还有IO操作的BufferOverflowException异常
2、非运行异常需要程序员手动去捕获或者抛出异常进行显示的处理,因为Java认为Checked异常都是可以被修复的异常。常见的异常有:
IOException
SqlException
A选项属于运行异常,不需要程序员手动捕获
B选项正确,属于运行时异常,数字字符串中出现英文字符,抛出数字格式化异常
C选项正确,属于运行时异常,Java著名异常,空指针异常,指的就是将一个引用赋值为空,如果操作这个引用会抛出空指针异常
D选项正确,属于检查异常,IO流异常需要程序员自己捕获
*/