Day5
左移运算符 << : 最左侧丢弃, 最右侧补0
右移运算符 >> : 最右侧丢弃, 最左侧补符号位
无符号右移 >>> : 最右侧丢弃, 最左侧补0注意:
左移一位相当于 *2, 左移 N 位, 相当于 *2 的 N 次方
右移一位相当于 /2, 右移 N 位, 相当于 /2 的 N 次方
这个题确实是属于脑瘫错误了
方法 operate 在启动时产生一个栈帧, x 和 y 都处在这个栈帧中, 这个栈帧在方法启动时产生, 在方法结束时销毁(具体可见博客 JMM)
栈中的变量 a 和 b 指向堆中 new StringBuffer 的 value 中的字符串对象"A" 和 “B”(字符串常量池)
在方法启动时, x 指向 a , y 指向 b.
append() 方法将 y 所指向的 b 所指向的堆中的 new String 对象中的"B"拼接到字符串"A"上, 此时这个字符串对象被修改成"AB"
而 y = x 只是将 x 的引用给到 y, 在方法结束时, x 和 y 也被一起销毁, 所以并没有对字符串对象造成什么影响
所以最后输出应该是 “AB.B”
B中 HashMap 实现的是 Map 接口
泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除
对于泛型参考:
https://blog.csdn.net/briblue/article/details/76736356?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159222702719725219921322%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159222702719725219921322&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_ctr_v3-1-76736356.ecpm_v1_rank_ctr_v3&utm_term=%E6%B3%9B%E5%9E%8B%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%93%A6%E9%99%A4%E6%9C%BA
思路: 采用递归的思想
1. 物品 n 个吗逐个放入 arr 数组中
2. 递归(剩余物品的重量, 剩余可选物品的个数)
递归过程:
(1) 从后往前装, 装上 arr[n] 后仍然可装, 就递归(s - arr[n], n - 1)
(2) 若装了 arr[n] 后不可装了, 则删除这个包, 递归下一个 count(s, n - 1)
public class Main3 {
private static int tmp;
private static int[] arr;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
arr = new int[n + 1];
for (int i = 1; i <= n; i++) {
arr[i] = sc.nextInt();
}
count(40, n);
System.out.println(tmp);
}
}
private static void count(int s, int n) {
if (s == 0) {
tmp++;
return;
}
if (s < 0 || s > 0 && n < 1) {
return;
}
count(s - arr[n], n - 1);
count(s, n - 1);
}
}
Day6
String(byte[] bytes, String charsetName) 通过指定的charset解码指定的bytes数组,
构造一个新的String; getbytes(Charset charset)使用给定的charset将此String编码到byte序列,
并将结果储存到新的byte数组.
B选项中: 先执行 new String (src, “GBK”), 通过"GBK"解码得到原字符串
再通过getBytes(“UTF-8”)重新将字符串编码, 得到UTF-8编码字符数组
A选项: copyonwritearraylist 适用于写少读多的并发场景
B选项: readwritelock – 读写锁, 他要求写与写之间互斥, 读与写之间互斥, 但是读与读之间可以并发执行, 所以在读多写少的场景下可以提高效率
C选项: concurrenthashmap 是同步的HashMap, 读写都加锁
D选项: volatile 关键字只可以保证多线程的可见性和防止指令之间的重排序, 不能保证原子性, 不能保证线程安全
分析一下上面代码的执行过程:
类加载的时候发现 HelloB.class 还有有一个父类, 然后先去加载HelloA.class
static 代码块在.class里执行的优先级比 main 高
所以在加载 HelloA.class 的时候, 会先执行 static 代码块中的语句 — 先打印"static A"
然后返回去继续加载 HelloB.class
结果发现 HelloB.class 里面还要个 static 代码块, OK, 还是先执行 static 代码块, 打印 “static B”
终于轮到 main 了, new HelloB(); 实例化的时候默认先调用父类的构造方法
又跑到 HelloA.class 里面去了, 先执行父类的初始化, 执行父类的实例代码块, 打印"Im A class"
终于轮到自己了, 执行自己的实例代码块, 打印"Im B class"
HelloB.class 哭晕在厕所里了, 太难了!!!
所以结合分析, 这道题输出为 B 选项
Semaphore 信号量 用于限制并发线程的数量
ReentrantLock 可重用锁
CountDownLatch 场景:任务需要在几个线程后才能执行,类似于一个计数器
Future接口是Java线程Future模式的实现,可以来进行异步计算。有了Future就可以进行三段式的编程了,1.启动多线程任务2.处理其他事3.收集多线程任务结果。从而实现了非阻塞的任务调用
分析一下执行过程:
运算符中, 关系运算符"= ="的优先级高于条件运算符 , 所以先执行 true == true , 返回 true;
然后两个选择语句的执行顺序是从后往前执行, 后面的语句为 true?false:true ==> 得到 false
然后执行前面的语句 true?false:false ==> 得到 false
所以 b 的值就是 false
思路很简单, 注意
- HashMap的遍历方法
- 输入n个空格分隔的n个整数怎么把数字逐一提取出来: 利用String的split(" ")方法, 利用每个空格, 将整个字符串分隔成数字字符的数组, 然后调用 Integer.parseInt()方法, 将每个字符串数组化为整数
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextInt()) {
HashMap<Integer, Integer> map = new HashMap<>();
String[] strs = sc.nextLine().split(" ");
for (int i = 0; i < strs.length; i++) {
int n = Integer.parseInt(strs[i]);
map.put(n, map.getOrDefault(n, 0) + 1);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() >= strs.length / 2) {
System.out.println(entry.getKey());
}
}
}
}
}
Day7
接口只能用public来修饰
对于四舍五入函数
Floor(): 向下取整, 会取不大于自变量的最大整数, 比如3.1或者3.9, 返回都是3;对于-2.1和-2.9, 返回都是-3
Ceil(): 向上取整, 会取不小于自变量的最大整数, 比如3.1或者3.9, 返回都是4; 对于-2.1和-2.9,返回都是-2
Round(): 才是要的四舍五入函数.
D选项 hasNext()方法是Iterater(迭代器)的方法, 表示是否存在下一个元素
Object类的方法:
1.clone方法
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
2.getClass方法
final方法,获得运行时类型。
3.toString方法
该方法用得比较多,一般子类都有覆盖。
4.finalize方法
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
5.equals方法
该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。
6.hashCode方法
该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
一般必须满足obj1.equals(obj2)==true。可以推出obj1.hash- Code()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
7.wait方法
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
(1)其他线程调用了该对象的notify方法。
(2)其他线程调用了该对象的notifyAll方法。
(3)其他线程调用了interrupt中断该线程。
(4)时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
8.notify方法
该方法唤醒在该对象上等待的某个线程。
9.notifyAll方法
该方法唤醒在该对象上等待的所有线程。