编程(面外企)常遇到的英文单词
机试 英语 formulation
java的foreach就是for
FileUtils.readLines() FileUtils里的函数是静态函数,不需要为FileUtils创建一个实例。
机试通用
快捷键的使用
ctrl+->
ctrl+shift+->
home
ctrl+enter ?
转滴答清单
在线做题和手撕注意事项
l 重复一遍面试官的题目,“让我想想”
l 一定要提前把边界测试列在边上,尤其是手撕的时候不能debug很容易最后漏掉边界,手撕的时候提前写在纸上。
n 把边界情况的处理步骤完全模拟好再动手!!!!
l 手撕,自己写个测试用例
l 手撕,试探对方这道题要求用什么时间复杂度去解
l 对照一遍题目看是否都按照题意处理了
l 程序debug之前先肉眼debug
n 先是写在一边的边界测试
l 有关数字的问题一定要考虑前置0, 如leetcode atoi
机试前
虚拟机
IDE准备好,把下面的写好
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(http://System.in);
int n,m,i,j;
l int index = 0, sign = 1, total = 0;
System.out.println();
}
}
只在main里写输入输入逻辑,主逻辑全部包装到一个函数内,便于硬编码测试用例。
摄像头
注意视频面试,键盘的声音 问你为什么键盘声音?我在做面试记录,方便回顾总结。
安静的环境(降噪耳机)
纸和笔、自动笔、各种颜色笔,橡皮
关闭闹钟
有交流的群
防作弊文本相似度匹配:
每个人都私聊 1人1道
更改代码结构,替换所有变量名
贴几段下面没有用的代码进去:
int ttt;
int ppp;
///fhdpoifhlsajfl;khsfl;hashd
while(false);
int ffff;
while(false);
copy一段代码然后注释掉放进去
通用做OJ题常识
数字(整型)溢出不会抛异常,不会报错。
机试时注意事项
l 机试时在网上临时找自己没有看懂逻辑的代码来套,历史成功率记忆中为0。 比如最长上升子序列自己会写,这种情况下一定要自己写,千万不要网上找代码或笔记里找代码,花的时间只会更多。
l 现在用随机算法最后AC结果都是0
JAVA
java内存的使用
合理使用 堆空间 和 方法区空间,不要只使用堆空间和栈空间。 类中的静态变量分配在方法区, 函数中的数组和对象分配在heap。
Java定义在类里的变量就是全局变量哦。
类型之间的关系问题
正确的两个整型相除得到double的方法
保证整数相除的double型结果能显示到2位小数以上:
int a = 20; int b = 300;
double ret = a/b; //结果可能为0.0
double ret = (double) a/b; 结果可能为0.0
double ret = (double) a / (double) b; //这样才是正确的用法 Java错题
Integer 转 int 的正确方法
正确: Integer.intValue()
错误: 使用强制类型转化的方法
字符串
String使用final修饰。内部实现char[]用final修饰,不可变,replace后要赋给新的字符串。
string要trim() ,只去掉两端的空字符。
String[] ss = s.split(" "); //注意返回值
字符串常量问题:
HashSet set = new HashSet();
set.add("1111");
char[] kk = new char[]{'1','1','1','1'};
String d = new String(kk);
System.out.println(d == "1111"); //返回false。 "1111"在编译阶段识别,会去寻找是否有已经存在的常量,
// String d在运行阶段产生,会生成新的"1111",而不是像编译阶段一样去寻找是否有已经存在常量。
if (set.contains(d)) //返回true。 contians内部是用equals比较两个对象的,而不是比较引用地址
System.out.println(true);
else
System.out.println(false);
char数组 字符数组
string转char数组/ 字符串转字符数组
char[] ch = s.toCharArray();
char数组转string/ 字符数组转字符串
String s = new String(char[]);
String s = new String(StringBuffer/StringBuilder);
String s = String.valueOf(ch);
String 转 string[] 每个字符作为一个字符串的经验:
先String.toCharArray(); 然后转成string[]
字符的处理
取得c=‘9’的int值, int digit = c - ‘0’;
字符顺序
我暂时认为unicode码的相对顺序和ASCAII一致
ASCAII码表顺序 0....9
A...a
ASCAII码a的值
输入
Scannar sc = new Scanner(new BufferedInputStream(http://System.in));
sout
sc.nextInt();
nextint后还需要调用一次nextLine才能开始读下一行
读取输入一个char
String s = sc.next();
char c = s.charAt(0);
sc读下一个字符 能否不借助 String? 不能
Java读入 1,333,444 格式的数据没有直接的好办法,目前最优就是字符串读入后split。
while (sc.hasNext())永远不会结束, 输回车是没有用的,除非windos上输入ctrl+z, linux上输入ctrl + d。
输出
System.out.printf("%d %10.5f", i, j);
Int最大值最小值
int是32位 , 2的32次方为4 294 967 296 (10位)
Integer.MAX_VALUE = 2的31次方 - 1 。 正数绝对值比负数是要小的 2147483647(10位)
Integer.MIN_VALUE = (-) 2的31次方 -2147483648
直接记住这两个数,编程的时候有的时候比用Integer.MAX_VALUE 、Integer.MIN_VALUE 来得直观。除非不是32位
判断一个字符串整型是否溢出:通过其位数判断
高精度
BigInteger(BigDecimal) 接口:
add、subtract、divide、multiply、mod
compareTo()
其他跟数字Double Long操作相关的接口也都有
BigInteger a = new BigInteger("11111");
BigInteger b = new BigInteger("-1");
System.out.println(a.compareTo(b)); //返回1
System.out.println(a); //输出 11111
BigDecimal.toPlainString 不使用科学计数法
给一个字符串1.238761976E-10
如何得到0.0000000001238761976这个字符串呢?
BigDecimal bd = new BigDecimal("1.238761976E-10");
System.out.println(bd.toPlainString());
不用再使用format了。
toEngineeringString:有必要时使用工程计数法。工程记数法是一种工程计算中经常使用的记录数字的方法,与科学技术法类似,但要求10的幂必须是3的倍数
快速幂取模算法可以防溢出 求 a^b mod c
代码:
int power(int a, int b, int c){
int ans = 1;
a = a % c;
if(b%2==1)
ans = (ans * a) mod c; //如果是奇数,要多求一步,可以提前算到ans中
k = (a*a) % c; //我们取a2而不是a
for(int i = 1;i<=b/2;i++)
{
ans = (ans * k) % c;
}
ans = ans % c;
}
/*快速幂算法 C++*/
int power2(int a, int b, int c) {
int res = 1;
a %= c;
while (b) {
if (b & 1)
res = (res * a) % c;
a = (a * a) % c;
b >>= 1;
}
return res;
}
着色问题,总的方案有 N^W种, 不产生坏账的方案有 N*(N-1)^(W-1)种,两者做差。
进制转化
n进制数A 转m进制数B 。先把A以String读入成str
将10进制的整型 转换成 base(base <= 35)进制的字符串
String st = Integer.toString(intNum, base); // 把intNum当做10进制的数转成base进制的st.(base <= 35)
将 base进制的String 转换成 (10进制)整型
1 、int num = Integer.parseInt(st, base); // 把st当做base进制,转成10进制的int(parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).
2 、 BigInter m = new BigInteger(st, base); // st是字符串,base是st的进制.
读入一个n进制形式的数 存储为BigInteger
1.将一个n进制形式的数读入,可以使用cin.nextBigInteger(n);
BigInteger 转换成 n进制字符串
如果要将一个大数转换成其他进制形式的字符串 使用String s = aBigInteger.toString(n);//将它转换成n进制表示的字符串
见 mycode J2SEReview In_Out_Array_wangyi_2019_intern
数学函数
Math.max(a,b);
Math.ceil() 向上取整
Math.floor() 向下
保留n位小数
通过String.format( "%.nf", aDouble)保留n位小数
还没记熟 考试的时候还是手写下面的几个功能比较快比较快。
Stream求List、Array等求平均、最大、最小等以及执行常见的算子
LongStream s = Arrays.Stream(rets[j]); //传入参数是一个数组
rets[j][10] = (long)s.average().getAsDouble();
rets[j][11] = Arrays.Stream(rets[j]).min().getAsLong(); //每次计算都需要重新执行Arrays.Stream(rets[j])
rets[j][12] = Arrays.Stream(rets[j]).max().getAsLong();
从Array转换为stream有两种办法,Stream.of()和Arrays.stream();在面对引用类型时,这两种方法都没有问题,而面对primitive类型的数组时,前一种方式却不能得到期望的结果,具体的解释看下面这个链接。
为了避免这个坑,我建议使用Arrays.stream(xxx)方式来处理array到stream的转换
project structer -> Modules-> sources下的language level 修改为更高等级
list.stream().allMatch((x) -> x == 555); // 检查是否匹配所有元素
list.stream().anyMatch(((x) -> x>600)); // 检查是否至少匹配一个元素
list.stream().noneMatch((x) -> x>500); //检查是否没有匹配所有元素
list.stream().findFirst(); // 返回第一个元素
list.stream().findAny(); // 返回当前流中的任意一个元素
list.stream().count(); // 返回流中元素的总个数
list.stream().forEach(System.out::println); //内部迭代
list.stream().max(Integer::compareTo); // 返回流中最大值
Optional min = list.stream().min(Integer::compareTo);//返回流中最小值
System.out.println("min "+min.get());
Collections执行最大、最小等算子
Integer[]numbers = {8, 2, 7, 1, 4, 9, 5};
intmin = (int)Collections.min(Arrays.asList(numbers));
intmax = (int)Collections.max(Arrays.asList(numbers)); 没有平均值接口
数组
数组不是对象,不存在成员方法,获取长度用 .length; String是类,用成员方法获取长度用 .length() .
二维数组:
board.length 是否用 一个变量代替,不是机试的瓶颈所在
注意 board.length 表示有n行
board[0].length表示有m列
声明和创建
正确:
int n = 3, m = 2; int[] f = new int[n]; 或int f[]
int []f[] 正确
Arrays.fill(f,2);
正确:
return new int[]{1,2};
错误:
return new int[2]{1,2};
Java数组最大长度
1、 array.length 是 int型,所以 array的长度不能超过 2^31
2、通过修改虚拟机的最大内存,java整型等各种类型数组的最大长度可以调整
Arrays
l Arrays.fill()
l Arrays.sort()
l Arrays.asList
l Arrays.copyOf
l Arrays.binarySearch()
n 需要先用Arrays.sort()排序
l Java Arrays.binarySearch()的返回值问题:
u 找到返回index(从0开始算),找不到返回(插入位置+1)的负数
u 为什么上面括号中不直接用插入位置? 假如这样做,插入位置为0时返回的是0,val出现在第一个位置时返回的也是0.
n 当val在数组中有重复元素时, there is no guarantee which one will be found.
l 之所以计算插入点值时索引要从1开始算,是因为-0=0,如果从0开始算,那么下面例子中关键字2和关键字4的返回值就一样了。
l 例子:
Arrays Comparator
对n*2列的二维数组定制化排序,按照每一行的第二个数升序排列:
int array[][] = new int[5][2];
Arrays.sort(array, new Comparator() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
在实现Comparator接口的对象中重写compare函数 ,定义在类外部的比较器
实现Comparable接口的对象才有compareTo()函数 定义在类内部的比较器
compareTo 如果要升序排列,那么前面小于后面的时候需要返回负值
集合类
使用泛型 实例化一个接口时要注意的问题
1、Map map = new HashMap();
2、Map map = new HashMap();
在1的情况下,编译器只能识别出map.get()是个Object的,而不能识别出map.get()是Integer, 也就是说当map.get()调用Integer的方法,如map.get().intValue()时会报错。
List list = new LinkedList();
list.poll(); //这一句是错误的,虽然LinkedList有poll接口,但是List没有poll接口
层次结构
1、 Iterable 接口
1.1、Collection接口
1) Set
1.1) HashSet
1.2) SortedSet接口
TreeSet
2) List
l LinkedList
n 双端队列,实现了栈的接口
u stack转list
l List list = new ArrayList(stack)
n 支持队列操作: pop() push(o)
n 支持 add/removeFirst()/Last()
n List list = new LinkedList();
u LinkedList支持poll接口,但LIst不支持poll接口,所以list不支持poll接口
1.2、Map接口
1) HashMap
1.1) LinkedHashMap
2) SortedMap接口 查询效率跟HashMap比怎么样?是一样的吗?如果一样的话感觉多用SortedMap岂不是更好,感觉HashMap的功能SortedMap都有吧
2.1) TreeMap
Java里多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)https://blog.csdn.net/debugingstudy/article/details/12716327,TreeSet应该能比HashMap提供更多功能,TreeSet的效率经过测试没有HashMap高。
LinkedList和 LinkedHashMap,它们实现的接口和提供的功能比较多,同时有多种数据结构的功能。不过LinkedHashMap相比HashMap的效率肯定是会下降的。
TreeMap 构造函数支持 Comparator, HashMap 不支持。
Collections.sort
Collections.sort能直接操作list,不能操作Set
【lamda】 Collections.sort( list, (x.y) -> x-y)
HashSet、 entryset()需要先转成list后操作
TreeSet自身支持排序。
【重要】自定义一个List排序规则,然后对另一个List按照该规则排序
String[] regulation = {"诸葛亮","鲁班","貂蝉","吕布"};
String[] ordered = {"貂蝉","诸葛亮","吕布","貂蝉","鲁班","诸葛亮","貂蝉","鲁班","诸葛亮"};
将 ordered按照 regulation里的顺序排序
Arrays.sort()
String[] cites
Arrays.sort(cities, (first, second) -> Integer.compare(first.length(), second.length()));
Arrays.sort(cities, Comparator.comparingInt(String::length));
Person[] a
Arrays.sort(a, Comparator.comparingInt(x -> x.think)); // 按照 think字段的 natural sort排序
Arrays.sort(a, Comparator.comparing(Person::name) )
//按照名字长度进行排序
Arrays.sort(arr,Comparator.comparing(Person::getName,(s,t)-> Integer.compare(s.length(),t.length())));
Arrays.sort(arr,Comparator.comparingInt(p->p.getName().length()));
//先按照名字进行排序,如果名字相同,再按照地址比较
Arrays.sort(arr,Comparator.comparing(Person::getName).thenComparing(Person::getAddress));
java.util.PriorityQueue基于堆实现,默认是最小堆。
peek add()或offer() poll()
C++ PriporityQueue默认是最大堆。
Lamda
LinkedList list; list.forEach( t -> sout(t+" "));