答题与解题(6)

Java SE专题

1、下面程序段执行后b的值是(B)。
Integer integ =new Integer(9);
boolean b = integ instanceof Object;
A、9
B、true
C、1
D、false

解题:Object是 integ 的父类

2、一个以”.java”为后缀的源文件 C
A、只能包含一个类,类名必须与文件名相同
B、只能包含与文件名相同的类以及其中的内部类
C、只能有一个与文件名相同的类,可以包含其他类
D、可以包含任意类

解题:一个.java文件中,只能存在一个类是用public修饰的,并且这个类必须与类名一致,文件中其他的类不能是public权限的,但可以有很多个类。

3、下面关于垃圾收集的描述哪个是错误的?(D)
A、使用垃圾收集的程序不需要明确释放对象
B、现代垃圾收集能够处理循环引用问题
C、垃圾收集能提高程序员效率
D、使用垃圾收集的语言没有内在泄漏问题

解题:java的垃圾收集机制主要针对新生代和老年代的内存进行回收,不同的垃圾收集算法针对不同的区域。所以java的垃圾收集算法使用的是分代回收。一般java的对象首先进入新生代的Eden区域,当进行GC的时候会回收新生代的区域,新生代一般采用复制收集算法,将活着的对象复制到survivor区域中,如果survivor区域装在不下,就查看老年代是否有足够的空间装下新生代中的对象,如果能装下就装下,否则老年代就执行FULL GC回收自己,老年代还是装不下,就会抛出OUtOfMemory的异常
内存泄露(Memory Leak)是指一个不再被使用的对象或者变量还在内存中占有存储空间
内存泄露主要有两种情况:
1.在堆中申请的空间没有释放。
2.对象已不再被使用(注意:这里的不在被使用是指对程序来说没有用处,如数据库连接使用后没有关。但是还是存在着引用),但是仍然在内存中保留着。

4、在java中,无论在何处调用,使用静态属性必须以类名做前缀。(B)
A、正确
B、错误

解题:此题考察静态关键字static
1如果是本类使用,可以直接就用静态变量名。
2如果是其他类使用,可以使用类名来调用,也可以创建一个实例对象来调用。
3如果静态变量所在的类是静态类,那么不管在本类里或者在其他外部类,都可以直接使用静态变量名。

5、执行下面的程序段,语句3的执行次数为(C)
for (i=0; i<=n-1; i++) (1)
for (j=n; j>i; j–) (2)
state; (3)
A、n(n+2)/2
B、(n-1)(n+2)/2
C、n(n+1)/2
D、(n-1)(n+2)

解题:假设代入法:
设n=3,外层循环i的取值为0,1,2
当i=0时,内部循环j的取值为3,2,1,所以state执行3次;当i=1时,内部循环j的取值3,2,所以state执行2次;当i=2时,内部循环j的取值为3,所以state执行1次。
综上所述:3+2+1=6次。将n=3带入选项中的出C符合结果。

6、检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。(A)

package algorithms.com.guan.javajicu; 
public class Inc { 
    public static void main(String[] args) { 
       Inc inc = new Inc(); 
       int i = 0; 
       inc.fermin(i); 
       i= i ++; 
       System.out.println(i);
    
    } 
    void fermin(int i){ 
       i++; 
    } 
}

A、0
B、1
C、2
D、3

解题:来用四段代码来解释,JVM的中间缓存变量机制。
int i = 0; i++; System.out.println(i); //值为1 打印的是表达式的结果 int i = 0; ++i; System.out.println(i); //值为1 打印的是表达式的结果 int i = 0; i = i++; System.out.println(i); //值为0 打印的是中间变量(JVM中间缓存变量机制) int i = 0; i = ++i; System.out.println(i); //值为1 打印的是表达式的结果

7、URL u =new URL(“http://www.123.com”);。如果www.123.com不存在,则返回______。(A)
A、http://www.123.com
B、””
C、null
D、抛出异常

解题:new URL()时必须捕获检查异常,但这个异常是由于字符串格式和URL不符导致的,与网址是否存在无关。URL的toString方法返回字符串,无论网址是否存在

8、变量a是一个64位有符号的整数,初始值用16进制表示为:0Xf000000000000000; 变量b是一个64位有符号的整数,初始值用16进制表示为:0x7FFFFFFFFFFFFFFF。 则a-b的结果用10进制表示为多少?(C)
A、1
B、-(262+261+2^60+1)
C、262+261+2^60+1
D、259+(255+254+…+22+21+20)

解题:硬智商算法题
0Xf000000000000000补码为1111000000000000000000000000000000000000000000000000000000000000
0x7FFFFFFFFFFFFFFF补码为0111111111111111111111111111111111111111111111111111111111111111
a-b=a+(-b)=
1111000000000000000000000000000000000000000000000000000000000000+
1000000000000000000000000000000000000000000000000000000000000001=
10111000000000000000000000000000000000000000000000000000000000001(高位溢出舍去)
则结果为
0111000000000000000000000000000000000000000000000000000000000001=
2^62+ 2^61+ 2^60+1

9、根据下面的代码,
String s = null;
会抛出NullPointerException异常的有(AC)。
A、if( (s!=null) & (s.length()>0) )
B、if( (s!=null) && (s.length()>0) )
C、if( (s==null) | (s.length()0) )
D、if( (s
null) || (s.length()==0) )

解题:逻辑运算符:&&和|| 是按照“短路”方式求值的。如果第一个操作数已经能够确
定表达式的值,第二个操作数就不必计算了。
位移运算符:&和| 运算符应用于布尔值,得到的结果也是布尔值,不按“短路”方式计算。即在得到计算结果之前,一定要计算两个操作数的值。

10、在 hibernate 开发中,关于 POJO 类对象的状态说法正确的是(ABC)。
A、自由状态(Transient):实体在内存中自由存在,与数据库中的记录无关
B、持久状态(Persistent):实体处于由Hibernate框架所管理的状态,对应了数据库中的一条记录,同时与某个session实例发生了关联
C、游离状态(Detached):在session 关闭之后,可以使对象从持久状态转换到游离状态。
D、不能将对象从游离状态转换成持久态

解题:此题表示很懵逼,所以给大家看看官方的解析
Hibernate Pojo的三态分别为transient(瞬时态),persistent(持久态),detached(游离态)
1、官方给出的三态与Session的关系如下:
transient: never persistent, not associated with any Session
persistent: associated with a unique Session
detached: previously persistent, not associated with any Session
2、三种状态间相互转换关系,及他们在数据库、session中的状态如下:
a.当我们new一个pojo时,它处于瞬时态,此时与session、数据库均无任何关联。
b.此后,我们获得session并开启hibernate事务,调用save(),persist(),saveOrUpdate()方法,将pojo转变为持久态,此时session中存有这个pojo,但直到transaction.commit()被调用时,sql语句才会执行,此后数据库中也才有此条数据。
c.但当commit()并且session.close()执行过后,pojo就变为了游离态,也就是说,数据库中有该记录,但session中不再有。
d.持久化状态的实例,也可以重新变成瞬时态,那就是调用delete()方法。
e.通过get()或load()方法得到的pojo是持久态的。
f.游离态的pojo可以通过update(),saveOrUpdate(),lock()和replicate()方法重新成为持久态。
g.调用merge()方法后,pojo维持原态,但内容会被更新到数据库

数组专题

1、设有一个二维数组A[m][n],假设A[0][0]存放位置在644(10),A[2][2]存放位置在676(10),每个元素占一个空间,问A[3]3存放在什么位置?脚注(10)表示用10进制表示(C)
A、688
B、678
C、692
D、696

解题:数学题,直接理清二维数组的规律进行运算就行, (676 - 2 - 644)/2 = 15

2、有两个NN的矩阵A和B,想要在PC上按矩阵乘法基本算法编程实现计算AB。假设N较大,本机内存也很大,可以存下A、B和结果矩阵。那么,为了计算速度,A和B在内存中应该如何存储(按行存指先存储第一行,再第二行,直到最后一行;按列存指先存储第一列,再第二列,直到最后一列)?(B)
A、A按行存,B按行存。
B、A按行存,B按列存。
C、A按列存,B按行存。
D、A按列存,B按列存。

解题:
我们来看看传统的分块矩阵相乘:
很明显依然是行乘以列的方式。
再来看看Strassen矩阵相乘:
同样是分块,只是计算方式不同
很明显,涉及到行的加法(a+b,c+d,e+f,g+h),列的减法(f-h,g-e,b-d,a-c),对角线的加法(a+d,e+h)以及行列的乘法,所以无论是
A按行存,B按行存。
A按行存,B按列存。
计算速度都是差不多的。
而如果用的是传统矩阵相乘法,按B选项的方式存储计算速度更快。综上所述,我觉得答案应该选B

3、顺序表结构适宜于进行随机存取。(A)
A、正确
B、错误

解题:顺序表指存储空间连续的表,如数组,支持随机存取。而链表(线性表的一种)不支持随机存取,访问时间复杂度o(n)

4、下列选项中,能正确定义数组的语句是( C )。
A、int num[0…2008];
B、int num[]={2008};
C、int N = 2008;
int num[N];
D、#define N 2008;
int num[N];

此题考察数组的定义
A选项[]里面错误,C选项定义错误,D选项宏定义不能有;号

5、在 C 语言中,一维数组的定义方式为:
元素类型 数组名[E];
E 为( D )。
A、常量表达式
B、整型表达式
C、整型常量或整型表达式
D、整型常量表达式

解题:定义的时候不能是变量,要注意强调一下常量所以选择D

数组编程题

1、给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
在这里插入图片描述
分析问题:当读完题目之后,我们就可以大概有个思路,意思就是将nums2中的元素复制到nums1中,当然这个完全能做,有一个问题是,这样的思路梳理下来,发现会忽略潜在性的因素,所以此时我们就先拿一个图来说明一下。
在这里插入图片描述
简单拿图画出来,对我们分析题目有很大的帮助。
<&>思路是我们先看第一种情况,我们将两个数组最大元素角标确定,然后分别比较两者大小,因为元素最后都要进入nums1,所以返回的nums1最大元素角标是不是也可以确定,通过比较谁大给返回的nums1最大角标走,然后最大角标-1,大的数组元素的最大角标-1,这样我们就可以将第一种情况完成。
那么第二种情况呢就是nums2中的元素存在没有比nums1中大的元素,那么是不是就意味着nums2中的元素没有移动到nums1中,此时相当于i2肯定是大于0,说明有元素,那我们只需要将nums2剩余的元素遍历进nums1即可。
代码实现:

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
		int i1=m-1;
		int i2=n-1;
		int i=m+n-1;
		while(true) {
			if(i1<0||i2<0) {
				break;
			}
			if(nums1[i1]>nums2[i2]) {
				nums1[i--]=nums1[i1--];
			} else {
				nums1[i--]=nums2[i2--];
			}
		}
		if(i2>=0) {
			for(int j=0;j<=i2;j++) {
				nums1[j]=nums2[j];
			}
        }
    }
}

2、给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
在这里插入图片描述
**问题分析:**同样拿到题,我们先进行分析。
这道题给我第一印象,无非就是将数组遍历,然后拿给出的值与每一个数组进行比较,如果没有就返回拿出值大于前一个元素的角标+1,有就返回当前元素的角标。但是我们仔细想想我们这样做是不是时间复杂度就上去了,所以我们为何不用我们学过的知识,二分查找你觉得可行?那图来说。
在这里插入图片描述
看图,这里我们用到二分查找算法,所以先比较你要找的值和中间元素谁大,这里中间大所以往左在进行查找,将rear指向mid,重新计算mid=1。再拿mid与所找值比较,发现所找值大mid,那么往右走将head指向mid,再计算mid,那么什么时候结束呢,是不是当它的head大于rear时,就结束。
当然这里的特殊情况时,当所找值等head或者rear或者mid时,直接返回对应的角标。
代码实现:

public static void main(String[] args) {
		int[] nums = {1,3,5,6};
		int target = 5;
		int i = new Test35().searchInsert(nums, target);
		System.out.println(i);
	}

	public static int searchInsert(int[] nums, int target) {

		int head = 0;
		int rear = nums.length - 1;
		int mid = (head + rear) / 2;
		if (nums[head] == target) {
			return head;
		}
		if (nums[rear] == target) {
			return rear;
		}
		while (head <= rear) {
			if (nums[mid] == target) {
				return mid;
			}
			if (nums[mid] < target) {
				head = mid + 1;
			} else {
				rear = mid - 1;
			}
			mid = (head + rear) / 2;
		}

		return head;

	}

3、给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
在这里插入图片描述
问题分析:
看题得出,无非就是给数组的最大角标元素+1就行,这样理解是正确的,但是往往会忽略哪些特殊的值,所以我们还是画图继续分析,更能明确各种特殊情况。
在这里插入图片描述
看图,题目说+1,那我们就定义一个变量为1,再定义一个数组数+此时这个1变得数sum,然后从数组得最大元素角标循环找,给它+1,然后做出判断特殊情况。先将sum进行取余,就是此时角标要放得元素,然后拿sum除以10,看此时坐标得元素+1后是否大于10,说明此时变量为1,那么就需要进行重建一个长度比之前数组长度大1得新数组,用来存放特殊例如1000,否则返回数组。
代码实现:

public static void main(String[] args) {
		int[] digits = {1,9,9};
		int[] is = new Test66().plusOne(digits);
		System.out.println(Arrays.toString(is));
	}

	public static int[] plusOne(int[] digits) {
		int index = 1;
		int sum = 0;
		for (int i = digits.length - 1; i >= 0; i--) {
			sum = digits[i] + index;
			digits[i] = sum % 10;
			index = sum / 10;
			if (index == 0) {
				break;
			}
		}
		if (index == 1) {
			int[] arr = new int[digits.length + 1];
			arr[0] = 1;
			return arr;
		} else {

			return digits;
		}

4、给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
在这里插入图片描述
解题思路此题通过看实例,觉得栈来做,相对于其他方法简单理解,首先你要创建一个栈,因为题给的是字符串,所以我们将字符串分别给它遍历成为字符,然后拿这些字符和栈进行操作。
那么此时就有两种情况
1、当栈为空时你直接将字符添加进去栈
2、当栈不为空,那么你首先要查看一下当前栈顶得元素,对其进行判断看当前栈顶元素减去当前遍历得元素是否等于-1或者-2(用字符之间得数字差),如果等于其中一个,弹出一个元素,否则将当前遍历得元素进行添加进栈。
代码实现:

 public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for(int i=0;i<s.length();i++){
            char a = s.charAt(i);
            if(stack.isEmpty()){
                stack.push(a);
            }else{
                char aa=stack.peek();
                if(aa-a==-1||aa-a==-2){
                    stack.pop();
                }else{
                    stack.push(a);
                }
            }
        }
        return stack.isEmpty();
    }

5、编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
在这里插入图片描述
**解题思路:**看题何为高效算法,那么就是意思它的时间复杂度不能超过O(n^2)。
在这里插入图片描述
根据图意那么需要从哪个角走,当你从1或者30走,是不是它相邻得两个方向都为比它小或者大,那肯定给方向判断起不到作用,那么就试试15和18发现都可以,那么我在这里就将18定位最开始得位置,当当前位置的元素大于所找元素向上走,小于则往右走,当然我们这里还有特殊情况
1、数组对象没有
2、对象有,没有数据
3、对象有,有行,行中没有元素
代码实现:

int row = matrix.length;
		int col = matrix[0].length;
		int x = row - 1;
		int y = 0;
		while (true) {
			if (x < 0 || y >= col) {
				return false;
			}
			if (matrix[x][y] < target) {
				y++;
			} else if (matrix[x][y] > target) {
				x--;
			} else {
				return true;
			}
		}
	}

6、给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
在这里插入图片描述
**解题思路:**由于之前做过类似的题,老师说通常遇到这种题,那么就需要使用滑窗来解决更方便。
在这里插入图片描述
当nums为空或者nums中没有元素,那么根据题意返回0;否则,我们需要一个计和数的和记录滑窗长度,还需要一个控制滑动的角标,当从0开始,往后走到3时大于等于s,那么记录滑窗长度,然后在想滑窗第一个元素删除,继续往后走,依次循环操作,当走到最后一个元素,也就意味着结束。
代码实现:

public static void main(String[] args) {
		int[] nums = {2,3,1,2,4,3};
		int s= 7;
		int i = new Test209().minSubArrayLen(s, nums);
		System.out.println(i);
	}

	public static int minSubArrayLen(int s, int[] nums) {
		if (nums == null || nums.length == 0) {
			return 0;
		}
		int len = 0;
		int i = 0;
		int sum = 0;
		for (int j = 0; j < nums.length; j++) {
			sum += nums[j];
			while (sum >= s) {
				len = len == 0 ? j - i + 1 : Math.min(len, j - i + 1);
				sum -= nums[i++];
			}

		}

		return len;

	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值