文章目录
面试
自我介绍:影响后面的谈话走向,有特点、技术互动、面试知识边界、写清楚,命名,逻辑。注释;当场写代码;有思路,写不出来,写伪代码,汉字,不要交白卷,沟通思路,没思路–尽快和面试官沟通:换题。让回去等通知,问他:大概什么时候能有通知;如果你足够优秀,不会让你等很长时间;途森:聊语言1小时,你做项目花了多少时间:思想的重视程度问题,项目中一定要能够突出细,博客最好项目有产出数据,之前面得怎么样?项目名称
开发环境+技术栈:项目过程:
条理化重点突出
项目难点/收获 总结
项目数据
url or二维码,你遇到什么问题,怎么解决的,优化地方,怎么优化,参考了其他什么,为什么做这个项目,
简历
有没有时间面试:不要往后推,他已经去找别人去了,不要想着再看1天,早干什么去了,1天你看不出来什么的;推到后面就什么机会都没有了,不要挑三拣四,最后什么都没了,笔试都过不了,你干了个什么;80%程序员薪资过不了20w,这行业人多,顶级人少,所以倒挂;不要和别人抬杠,没有意义;什么学校、什么学历给什么薪资都是薪资体系完善的,不是hr说了算,你期望什么薪资:如果觉得有困难、我说的太高或者太低可以商量;笔试:代码、面试:数据库、网络、操作系统,
做好准备,的有充分的消息来源(那家公司招聘,在哪网申请,deadline是什么时候,了解一下你要面的公司,了解一下公司的主要产品,面经])hr(情商面试,稳定性
自我介绍:写到备忘录上,背会,对别人称呼:和别人拉近距离,老师、姐,学习经历:主要学习xx,看别人博客,如⭐,视频 公众号 书,籍贯+姓名,最擅长的 ,明确求职意向,时间:60秒~90秒,
6月:1、系统的按模块复习,比如先复习c,总结出c常考所有知识点
2、牛客网刷这个部分的选择题
3、做好复习整理笔记
4、结队复习(尤其建议表达不好的同学使用>
5、等着所有模块复习完,再看面经
7月 8月:提前批:笔试最难,提前投简历找工作目的:经验,到了9月至10月才会真正找到好工作;秋招9月,你会感觉每天都在错失公司,800家公司要在60天招完人,笔试1天3家早中晚极限,头昏脑胀,睡觉时都感觉在在笔试,中间还穿插的有面试,自己逼自己解决问题:查文档、看源代码,逼得自己调试目的:经验,进公司带你的导师,给你分任务,是间接的领导。提前实习,9到11月:试用期。就那么2个月好好找工作,到处跑,面试时积极面貌、心态,抱团找工作,不要管抱的是java还是什么,1个人找是很痛苦的。如果你牛逼,有什么被打击的呀,今天这家被拒,明天还有几十家来,如果你本来就菜,还不让人打击你了?打击你的也不止这1家,8月找到工作:40%,10月之前:80%;
春招:考研、考公失败的人,
什么时候去实习:如果学校的事情处理完,我可以暑期。选择是双向的,
Linux一定要多用,指令是记不住的;系统和网络要结合练习多理解;语法也一样,要结合练习多理解,形成知识的结构化;提前批的前提是扎实,想想学这些知识的意义是什么,这东西到底是干什么的,梳理博客;
1.接口类型----题目已经将要实现的方法的函数原型提供好了,
用户只需要在函数中写代码就可以了
2.IO类型
1.需要提供main方法
2.如果用到对应的库函数,需要用户自己包含对应的头文件
3.一般都有多组测试用例,因此需要循环输入方式接收每组测试用例
4.一定要注意输入和输出的格式
二刷的时候希望可以对题目有所侧重,主要还是巩固思路,理解好每一题的算法。
代码的技巧性就靠多练多写多看了
操作符
%m. ns:
m:输出字符串的宽度
n:左起截取目标字符串n个字符,右对齐,补空格,精度,
printf("%s , %5.3s\n" ,"computer" ,"computer"");
结果:computer,空格空格com
printf("%%%%\n");//结果:%%
%d—>按照整形方式打印;%f—>按照float的方式打印,
格式串有一定规定,%之后跟上特定的字符才代表一定的格式,如:%Q—>无效的格式---->编译器会忽略%,直接输出Q
char a[10]={ '1","2','3', '4' ,'5''6''7','8','9','0'},*p; int i;
i=8;
p=a+i;
printf("%s\n",p-3);//%s遇到\0停止,结果:6789
代码1:for(n=O;getchar()!='\n';n++);
代码2:n=0;for(ch=getchar();ch!='\n';n++);
统计出一行中输入字符个数(不包含回车符):代码1;代码2:for循环的ch=getchar()只会执行1次,只获得1个字符
int a=1,b=2,c=3,d=0 ;
if(a == 1 && b++==2)
if(b!=2||c--!=3)//真||假,假不会被执行
结果:a=1,b=3,c=3,
int a=10 ; double b=3.14;则表达式’A’+a+b值的类型是:double;‘A’:char类型
int fun(int a);a^=(1<<5)-1;
return a ;
fun(21)=10=21^31
(1<<5)=0010 0000=32
或运算(|):只要有一个为1,其值为1;异或运算(^):两个相应位为“异”(值不同),则该位结果为1,否则为0;与运算(&:两位同时为“1”,结果才为“1”
一定可以可以将flag的第二个bit置0:flag = flag & (~2)即flag &=~2;
假设flag=10=0000 1010,0000 1010&1111 1101=0000 1000,1111 1101取反:0000 0010=2
题目:二维数组X按行顺序存储,其中每个元素占1个存储单元(字节)。若X[4][4]的存储地址为0xf8b82140,.X[9][9]的存储地址为0xf8b8221c,则X[7][7的存储地址为:0xf8b821c4
A(int aa,int bb){
a=aa--;b=a*bb;},则执行Ax(4,5);
//a=4,aa=3,b=20
计算日期到天数转换
#include<iostream>
using namespace std;
//判断闰年
bool isLeap(int year){
return (year % 4 == 0&&year % 100 != 0) || (year % 400 == 0);
}
int getDaysByYM(int year, int month)
{
int days[13] = { 29, 31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && isLeap(year))
month = 0;
return days[month];
}
int getDaysByYED(int year, int month, int day)
{
int days = 0;
for (int i = 1; i < month; ++i){
days += getDaysByYM(year, i);
}
days += day;
return days;
}
int main(){
int year, month, day; int days = 0;
while (cin >> year >> month >> day){
days = getDaysByYED(year, month, day);
cout << days << endl;
}
return 0;
}
最小公倍数
正整数A和正整数B的最小公倍数是指能被A和B整除的最小的正整数值,A和B的最小公倍数。
方法1.暴力
两个数中较大的数开始,逐个进行判断,能够被两个数都整除,则第一个就是最小公倍数
#include <iostream>
using : namespace std;
int main()
{
int A, B;
while (cin >> A >> B)
{
int m = max(A, B);
while (1){
if (m%A == 0 && m% B == O)
{
cout << m << endl;
break;
}m++;
}
}
return 0;
}
方法2:
#include <iostream>
using : namespace std;
int gcd(int a, int b){最小公约数:辗转相除法
int c;
while ((c = a%b)){
a = b; b = c;
}return b;
}
int main()
{
int A, B;
while (cin >> A >> B)
{
cout << A*B / gcd(A, B) << endl;两个数的乘积,除以最小公约数
}
return 0;
}
不得使用+或其他算数运算符
class UnusualAdd
{
public:
int addAB(int A, int B)
{
if (A == 0) return B;
if(B == 0) return A;
int a = A^B;//不考虑进位时候相加的结果....
int b =(A & B)<<l;//计算进位的数据
return addAB(a,b);一直递归,直到A=0或者B=0
}
};
46579 --计算糖果(数学题)
#include<iostream>
using namespace std;
int main()
{
int a,b,c,d;
cin>>a>>b>>c>>d;
int A=(a+c)/2;
int C=(d-b)/2;
int B1=(c-a)/2;
int B2=(b+d)/2;
if(B1!=B2)
cout<<"No";
else
cout<<A<<" "<<B1<<" "<<C; return 0; }
预测比赛
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次:
int main()
int a = 0;int b = 0;int c = 0;int d = 0;int e = 0;
for(a=1;a<=5;a++){
for (b=1; b <= 5; b++){
for (c=1;c< =5;c++){
for (d= 1; d<= 5;d++){
for (e= 1;e<= 5;e++){
if (((b==2) + (a==3) == 1)&&
((b==2) + (e==4) = 1) &&
((c==2)+ (d=2 )= 1)&&
((c==5)+(d==3) = 1)&&
((e==4) + (a==1)= 1))
{if(a*b*c*d*e == 120)
printf("a=%d b=%d c=%d d=%d e=%d\n". a,b,c,d.e);
}}}}}
return 0;}
58541-进制转换
#include <iostream>
#include<string>
#include<algorithm>
using namespace std;
int main() {
string s, table="0123456789ABCDEF";
int m,n; cin>>m>>n;
bool flag = false; // 如果是负数,则转成正数,并标记一下
if(m < 0) { m = 0 - m; flag = true; }// 按进制换算成对应的字符添加到s
while(m)
{
s += table[m%n];
m /= n;
}
if(flag) s += '-';
reverse(s.begin(), s.end());
cout<<s<<endl;
return 0; }
数据存储
1B(byte,字节)= 8 bit(位)
int a, b, c;
a = 5;
c = ++a;
b = ++c, c++, ++a, a++;//a=c=8,b=8
b += a++ + c;//a先和c加,结果为16,在加上b的值7,比的结果为23,最后给a加1,a的值为9
printf("a = %d b = %d c = %d\n:", a, b, c);
全局变量默认初始化为0,-1按无符号解释:42亿,npos=-1,表示size_t的最大值,许多容器都提供这个东西,用来表示不存在的位置。
i=-1;
(i > sizeof(i))//sizeof:无符号 有符号的-1转为无符号的,再比较大小,
char c= 'c';//把字符C赋给char类型,发生隐式转化或者截断问题
printf("%d\n", sizeof(c));//1,字符类型
printf ("%d\n", sizeof('C'));//4,字符整数
// \0和0在底层二进制序列一样,类型不一样,
浮点数不能直接比较,浮点数转为2进制序列时有精度损失:
unsigned char a = 200;
unsigned char b = 100;
unsigned char c = 0;
c = a + b;
printf(“%d %d”, a+b,c);
printf在传入参数的时候如果是整形会默认传入四字节,所以a+b的结果是用一个四字节的整数接收的,不会越界。而c已经在c = a + b这一步中丢弃了最高位的1,所以只能是300-256得到的44了。printf是可变参数的函数,所以后面参数的类型是未知的,所以甭管你传入的是什么类型,printf只会根据类型的不同将用两种不同的长度存储。其中8字节的只有long long、float和double(注意float会处理成double再传入),其他类型都是4字节。所以虽然a + b的类型是char,实际接收时还是用一个四字节整数接收的。另外,读取时,%lld、%llx等整型方式和%f、%lf等浮点型方式读8字节,其他读4字节。
二进制:101010b
八进制:0到7
十六进制:0x123或者123h,A=10,B=11
%o:八进制方式输出;%x: 十六进制方式输出
10进制转n进制,数字除以n,余数倒着排列即是想要的结果;123的8进制:173;
大小端
union un {
char c;
int i;}
int main()
{union un x;
x.i = 1;
if (x.c == 1){
printf("小端\n"):}
else {
printf("大端\n"):}}//小端,低权值放低地址
32位下:
long long a = 1, b = 2, c = 3;
printf("%d %d %d\n", a, b, c);//1,0,2
水平值总和max
题目:组队竞赛
贪心算法:每次选值时都选当前能看到的局部最解忧,每组的第二个值取到能选择的最大值,排序后 :
分为3组:[189][267][345]时是最优解,arr.length=9
用公式arr[arr.length-2*(i+1)]计算得下标为3 5 7的数(即4+6+8)水平值总和max
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() { // IO型OJ可能会有多组测试用例,持续接收输入多组测试用例。
int n; while (cin >> n)
{
long long sum = 0;
vector<int> a;
a.resize(3 * n);
for (int i = 0; i < (3 * n); i++)
{
cin >> a[i];
}
std::sort(a.begin(), a.end());
for (int i = 0; i < n; i++)
{
sum += a[a.size() - (2 * (i + 1))];
}cout << sum << endl;
}
}
7.只出现一次的数字
添加链接描述
找一个数字把里面所有的数字都异或一遍,异或两次=没异或。那么如果有两个数字都只出现了一次,那么如此得到的应该是两个数异或的结果。首先这个结果肯定不是0(要不然就全都配对了),所以里面一定至少一位是一。找出值为1的一位,以这一位的值将结果分为两组。例如1 2 3 4 1 2,异或完的结果应该是3^4得到的111,那么随便找一位就行了。例如找最低位,那么这一位是1的有1 3 1,是0的有2 4 2,利用异或结果为1的某一位分的组,所以两个待查询数字一定分别在两组中。所以再找两个变量,分别异或两组数,
void findData(int a[],int num,int *xp,int *yp)
{assert(xp);assert(yp);
*yp=0;*xp=0;
int res = a[0];
for (int i = 1 ; i < num; i++)整体异或
{res ^= a[i];
}//合
int flag = 1;//分开.分解找到第一个比特位为1,这里从低往高进行
int i = 0;
while (i < sizeof(int)){
if (res & flag){
break ;}
flag <<= 1;i++;}
for (int i = 0; i < num; i++){
if (flag & a[i]){
*xp ^= a[i];}//A组
else {
*yp ^= a[i];}}//B组
}
int main(){
int a[] = { 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,9 ,10};
int num = sizeof(a) / sizeof(a[0] ) ;
int x =0;int y = 0;
findData(a,num,&x,&y) ;
printf("%d,%d\n", x,y) ;// 9,10
}
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2)
{ if(num1 == nullptr || num2 == nullptr)
{ return; }//第一步先整体异或
int result = data[0];
for(auto it = data.begin()+1; it != data.end(); it++)
{ result ^= *it; }//第二步,分解找到第一个比特位为1,这里从低往高进行
int flag = 1; int length = sizeof(int);
for(int i = 0; i < length; i++)
{ if((flag << i) & result)
{ flag <<= i;
break; } }//第三部,分组异或
*num1 = 0; *num2 = 0;
for(int i = 0; i < data.size(); i++)
{ if(data[i] & flag)
{ *num1 ^= data[i]; }
else
{*num2 ^= data[i]; } } }
res一定不是0! res的二进制序列中,一定至少有一个1,x, y二进制,相同的部分一定是0,不同的部分一定是1,反过来,如果res中有一个比特位是1,一定是x,y对应比特位是不同的,成对的数据,第flag标志位对应的二进制值一定是一样的;不成对的,该位置一定不同;按照flag进行分组,flag == 0,flag == 1两组,成对的数据被分到了同一个组,不同的数据,一定被分到了不同的组;
A组:所有数据全部是成对的,只有一个是单独的!
B组:所有数据全部是成对的,只有一个是单独的!
左移不是往左移动,是往高位移动。
取先整体异或,异或结果一定不为0,而其中为1的比特位,不同的两个数据该 位置上的数据一定不同,用该比特位进行分组 //分组的结果一定是,相同数据被分到了同一组,不同数据一定被分到了不同的组
方法2:
int* singleNumber(int* nums, int numsSize, int* returnSize){
int ret = 0;
for (int i = 0; i < numsSize; ++i)//遍历所有的数字
{ret ^= nums[i]; //0^任何数=任何数,2个相同数异或(相异=1)=0,
//把所有数异或,则只剩下:出现1次的数的异或的值=ret= x1^x2
}
int m = 0;//找出ret里面第m位为1,说明x1和x2的第m位不一样,一个为1一个为0
while (m < 32) //x1和x2都是32位的数字
{ if (ret & (1<<m)) //与
break; //找到了第m位为1,跳出
else
++m;
}//去原数组里分离x1、x2,不会写时:找规律、举栗子
//第m位为1的为一组,第m位为0的为另外一组,x1和x2各在1组,其他数成对出现在某一组
int x1 = 0, x2 = 0;
for (int i = 0; i < numsSize; ++i){
if (nums[i] & (1 << m))//判断第m位是1还是0
{ x1 ^= nums[i]; }
else{ x2 ^= nums[i]; }
}//使用数组前提前开空间
int*retarr = (int*)malloc(sizeof(int)* 2);
retarr[0] = x1; retarr[1] = x2;
*returnSize = 2;//数组大小
return retarr;}
1、返回二进制中 1 的个数
比如: 15 0000 1111 4 个 1
int CourtOne(int x){//方法1:
int flag = (1 << 31);//1左移31位,到最高位
int count = 0;
while (x){
if (x & flag){//判断是否=1
count++;
}
x <<= 1;//逻辑左移,最终=0
}return count;
}
int CourtOne(int x){
int count =0;
while (x){//方法2://n和n-1按位与,将n二进制序列中最后一个出现的1变成0,直到这个二进制序列全部变成0.
//统计这个过程做了几次就是出现了几次1
x&=(x- 1);count++;}
return count;}
int main(){
int x = -1;//符号位参加运算
int c = CourtOne(x);
printf("count=%d\n", c);
system("pause");
return 0;}
#include <iostream>//方法3:
using namespace std;
int count(size_t value){
int count = 0;
while (value){
value &= (value - 1);
count++;
}
return count;}
int main()
{
size_t value; // unsigned int
int one_count = 0;
while (cin >> value){
one_count = count(value);
cout << one_count << endl;}
return 0;
}
最大连续bit数
#include <iostream>//方法1:
using namespace std;
int main (){
int num;
while (cin >> num){
int count = 0, max_count = 0;
while (num)
{//判断某一位是1或者0:num往右移动1位,逐个和1相与&
if (num & 1){
count++;
max_count = max(count, max_count);
}//max(统计连续1的个数, 保存当前最大连续1的个数)
else{
count = 0;
}num = num >> 1;
}
cout << max_count << endl;
}
return 0;
}
num右移,则高位补符号位,正数补0,负数补1,当num=-1时,高位一直(死循环)补1,计算得:-1有无穷个1,方法2不会出现此问题,修改while (num)及以下的内容为:
for(int i = 0; i <32; i++)num最多有32位
{ 1往左移动,和num的每个位的数字相与&
if(num & (1 << i)){
count++;
max_count = max(count, max_count);
}
else {count = 0;
}:方法2
2、两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同
输入例子:1999 2299输出例子:7
//先将m和n进行按位异或,此时m和n相同的二进制比特位清零,不同的二进制比特位为1
//统计异或完成后结果的二进制比特位中有多少个1即可
int CourtO(int x,int y){
return CourtOne(x^y);
}
}int main(){
int x = 10; int y = 1;
int c = CourtO(x,y);
printf("count=%d\n", c);
system("pause");
return 0;}
3、获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
void Show1(int x,unsigned int flag)
{
while (flag){
if(x& flag){//隐式转化,只是转化类型,不会改变数据本身
printf("1 ")://判断某1位,使用&
}
else
printf ("0 ");
flag>>= 2:}
printf("\n"");}
void Show2(x){
Show1( x,1<< 31);//偶数
Show1( x,1<< 30);
}
int main(){
int x = 10; Show2( x); system("pause");
return 0;}
2进制插入
class BinInsert{方法1
public:
int : binInsert(int n,int m, int j, int i)
{
for (int k = 0; k <= i-j; k++){
n |= ((m >> k) & 1) << (j + k);
return n;
}
};//(m >> k) & 1):把m的每一位取出来;<< (j + k):左移j+k位,
int : binInsert(int n,int m, int j, int i)方法2
{ return n |= (m <<j);m左移j位,再和n或
}
组成一个偶数最接近的两个素数
bool is_prime(int num){
for (int i = 2; i <= sqrt(num); i++)
{
if (num % i == 0){
return false;
}
}
return true;
}
int main(){
int num;
while (cin >> num){
for (int i = num / 2; i >= O; i--){
//i··· 'num-i判断同时是紊数
if (is_prime(i) && is_prime(num - i)){
cout << i << endl << num - i << endl;
break;
}
}
}return 0;
}
走方格的方案数
#include <iostream>
using :namespace std;
int pathnum(int n,int m)
{
if (n == 0||m == O)
{return 1;
}递归
return pathnum(n-1,m) + pathnum(n,m-1);
}从右下角开始走,其走法=上面格子的走法+左面格子的走法
int main(){
int n, m;
while (cin >> n >> m){
cout << pathnum(n, m) << endl;
}
return 0;
}
井字棋
玩家棋子:1时,整个一行相加结果为列数,就获胜了整个一列相加结果为行数,就获胜了,正斜:board[row][row],副斜: board[row][col -i -1]
class Board {
public :
bool checkWon(vector<vector<int> >board){
int co1 = board[0].size(); int row = board.size();
// 每一行是否连续
for (int i = O; i < row; i++){
int sum = 0;
for (int j = 0; j < col; j++){
sum += board[i][j];
}
if (sum == col) return true;
}
//每一列是否连续
for (int i = 0; i < col; i++){
int sum = 0;
for (int j = 0; j < row; j++){
sum + = board[j][i];
}
if (sum == row) return true;
}
//正斜是否连续
int sum = 0;
for (int i = 0; i < row; i++){
sum += board[i][i];
}if (sum == row) return true;
//副斜是否连续
sum = 0;
for (int i = 0; i < row; i++){
sum += board[i][col -1-i];
}
if (sum == row) return true;
return false;
}
};
密码强度等级
int size 0, sum = 0;
for (auto ch : str){
if (ch >= 'a'&&ch <= 'z'){
lower++; charc++;
else if (ch >= 'A'&&ch <= 'Z'){
upper++; charc++;
}
else if (ch >= '0'&&ch <= '9'){
digit++;
}
else if (ch >= 0x21 && ch <= 0x2F)||
(ch >= 0x3A && ch <= 0x40)||
(ch >= 0x5B && ch <= 0x60)||
(ch >= 0x7B && ch <= 0xFE)){
symbol++;
}
}
}size = str.size();
if (size <= 4)
sum += 5;
else if (size<=)
完全数计算
#include<iostream>
using namespace std;
int A(int n)
{
int count=0, sum=0;
for (int i = 2; i <= n; ++i)
{
for (int j = 1; j<i; ++j)
{
if(i%j == 0)//对约数进行求和.... · ·
sum+=j;j是i的约数
}
if(sum==i)
count++;
sum=0;开始下一个数的计算
}
return count;
}
int main(){
int n, count;
while (cin >> n){
count =A(n);
cout << count << endl;
}
return 0;
}
HJ37 统计每个月兔子的总数
#include<iostream>
using namespace std; /*//迭代法求解
int Fib(int n)
{
if(n <= 2) return 1;
int f, f1=1, f2=1;
for(int i=3; i<=n; ++i)
{
f = f1 + f2; f1 = f2; f2 = f;
}return f;
}*/
//递归法求解
int Fib(int n)
{
if(n <= 2) return 1;
else
return Fib(n-1) + Fib(n-2);
}
int main(){
int month; int sum =0;
while (cin >> month)
{
sum = Fib(month);
cout << sum << endl;
}
return 0;
}