28岁,从字节退休了···_28岁退休

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

小澜觉得,在字节不仅有技术的提升,学到了更加规范的工作流程,也接触到了更多的资源,字节“大厂”的身份也给自己的履历加了分,让自己能有机会获得更高的平台和更多良好的职业发展。

这些是字节作为互联网大厂给到小澜的成长。她也认为,对于年轻人,特别是应届毕业生,去大厂工作还是很有必要的,是一种人生体验,如果不进到大厂里,永远会觉得自己是围城外的人。

02、所有人都适合字节范儿吗?
80后的王希在字节已经不算年轻了。在进字节之前,他在业界也有了一定的能力和名声,用他的话来说,他算是陪着一批互联网公司一起成长起来的。

传闻中字节最卷的三大部门有:飞书、电商、本地生活。

在入职字节飞书后的王希彻底失去了个人的生活和娱乐空间。

“无意义的飞书加急,还有各种‘拉齐’的会议。”王希讲自己每天要参加6-7个会议,离谱的是还会出现“会议套会议”的情况,明明开着一个会,还有在线给另一个会发言,一天就在会议中完结。

而且他发现本质相同的一件事情,经常三四个部门一起干,甚至有的部门已经提前两个月在做,再往下推进的时候,各个部门再开会拉齐,消耗了一天大部分时间。

喜欢和商家与用户待在一起解决问题的王希最终决定离职,再次回到那个“纯粹的”小公司里。

03、留在大厂几年,实现财务自由也很香
同样是打工:有人28岁还在苦苦谋求一份大厂工作,而有的人28岁实现财务自由,选择退休!

知乎一篇《如何看待年仅28岁的郭宇宣布从字节跳动退休》的帖子,近1100多万的浏览量。

郭宇是前字节跳动资深技术专家。高中就自学代码,大三拿到支付宝offer,后加入字节拿到期权,28岁实现了财务自由从字节退休!

不少人感叹:一样的28岁,不一样的人生。

在那条知乎问题下面,有一篇郭宇朋友的回答文章,从他朋友的回答里,我们可以了解到一位真实的程序员成长路径。

高中就读于深圳名校,全国重点高中,而这所高中腾讯5位创始人,有4位毕业于此。

高考之后考入了暨南大学,他的专业却是政治与行政管理,专业是自己选的但是他不怎么去上课。

旷课的时间他不是像普通学生那样睡觉、打游戏,他利用这些时间去自学编程,在宿舍熬夜学习写代码。

大二开始就已经在找实习,能够早早不拘泥于大学课业的束缚,明确自己的目标,也是他的过人之处。大二面试腾讯,挂在第三面,大三终于拿到支付宝的实习。

非计算机专业出身,全靠自学做到这种程度,叫做逆天。自然郭宇的大厂履历很丰富。

2011年,大三去支付宝实习,留任前端开发工程师,正是在支付宝的这三年为他积累了深厚的互联网经验。

之后他自己创业误打误撞被字节跳动收购了,从此他的字节跳动工作生涯开启。

2014年到2020年,在字节的6年间,他的职位已经是资深技术专家,在这6年间,字节跳动估值暴涨,而他获得了字节跳动的期权。

郭宇后面自己说了他从字节离开,不是辞职是退休,是告别自己的互联网职业生涯,他28岁的理想是旅行在东京开旅馆,泡温泉。

成功的人生往往不可复制,且成功的标准不一,但相同的是,为了实现自己目标或是人生理想为此要付出的汗水与努力。

不管是郭宇还是其他程序员,不断的学习是必不可少的,学好手上的编程技术,踏踏实实做梦,勤勤恳恳敲代码,有了技术的的底气才能更好的一步一步实现自己的目标。

人生短短三万天,郭宇没有选择本专业的工作,而是决定踏入互联网行业,并且追逐到了自己想要的自由。

而现在各大厂的年包价动辄50万+,比起其他行业,IT互联网的天花板依然无疑是最高的。在互联网行业,相信会有更多的人凭技术说话过上自己想要的生活。

为了助力程序员朋友们跳槽面试、升职加薪、职业困境,提高自己的技术,本文给大家整了一套涵盖软件测试面试进阶所有技术栈的快速学习方法和资源。

内容涵盖:测试理论、Linux基础、MySQL基础、Web测试、接口测试、App测试、管理工具、Python基础、Selenium相关、性能测试、LordRunner相关等专题技术点,都是在各个大厂总结出来的面试真题,已经有很多朋友靠这份 PDF 拿下众多大厂的 offer,今天在这里总结分享给到大家!

测试基础(38页)
功能测试(183页)
linux(221页)
Mysql(216页)
接口测试(338页)
Jmeter(41页)
测试工具(35页)
web自动化测试(50页)
selenium(55页)
python编程(27页)
app自动化测试(66页)
性能测试(40页)
安全测试(21页)
测试开发(31页)
简历模板(38页)
注:篇幅有限,资料已整理成文档,整体的内容知识点也是偏多的,截图是截取不完的,所以请各位朋友注意:若是需要下载整个软件测试面试宝典,有需要的读者朋友们可以帮忙三连支持一下,点击文末小卡片传送门即可入手~

一、基础知识–2023版

(包含计算机基础、测试理论、HTML基础、CSS基础、JS基础常见的面试题**)**

二、Linux和数据库 --2023版

(包含 linux、数据库介绍、SQL语言(重点)、数据库高级功能常见的面试题**)**

三、编程+数据结构–2023版

(包含 Python基础、面向对象、异常处理、模块和等等常见的面试题**)**

四、WEB自动化–2023版

(包含 WEB自动化入门、WEB自动化基础、WEB自动化中级、WEB自动化高级、项目实战等等常见的面试题**)**

五、移动自动化 --2023版

(包含 移动自动化基础、移动自动化中级、移动自动化高级等等常见的面试题**)**

六、接口测试–2023版

(包含 接口基础、postman实现接口测试、数据库操作、代码实现接口测试、持续集成、接口测试扩等等常见的面试题**)**

七、接口自动化–2023版

(包含 接口自动化脚本编写、接口自动化测试执行、接口自动化测试报告分析****等等常见的面试题**)**

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以戳这里获取

<think>好的,我现在需要解决这个问题。让我仔细读题目要求。题目大意是,给定n个幸运符,每个的编号是1到n。每个幸运符对应的二进制编码是30位的0或1。然后有t天查询,每天给出一个数字x,要求找出所有编号对应的二进制转十进制后,包含x这个数字的幸运符。输出这些编号,按升序排列,没有的话输出空行。 首先,我得明确问题的关键点。每个幸运符的二进制转换成十进制后的数值,是否包含当天的x这个数字。比如,如果x是0,那么十进制数里得有0。比如0就包含0,而10的话也包含0。要注意的是,其他十进制数的前导零被忽略,所以比如二进制是0001的话,转换成十进制是1,这时候不考虑前导零,所以里面的数字是1,不含0。 那问题的解决步骤应该是这样的: 1. 预处理每个幸运符的二进制对应的十进制数。 2. 对于每个十进制数,将其转换为字符串形式,检查是否包含当天的x字符。 3. 对于每个查询x,遍历所有幸运符的十进制数,找出符合条件的编号,排序后输出。 那如何处理二进制转十进制呢?输入的二进制是30位,且从高位到低位排列。比如,输入的每一行有30个0或1,例如“1 0 1 0 ...”这样的形式。需要把这些转换成十进制的数值。这里需要注意的是,30位的二进制数可能很大,可能会超过普通的整数类型的范围。比如30位全1的话,是2^30-1,大约是10^9左右。而C++中的int通常是32位的,可以容纳这个数值,所以用long long应该没问题。但可能需要用更大的类型,比如unsigned long long或者直接处理字符串转换后的数值? 不过,其实题目中的二进制是30位,最大是2^30-1=1,073,741,823,这个数值在C++的unsigned int中是足够的,因为unsigned int在大多数系统上是4字节,最大到4,294,967,295。所以用unsigned int或者unsigned long long都可以。 但是,如何将这30位的二进制转换为十进制数值呢?输入的每一行的30个数字是空格分隔的,所以需要先处理这30个二进制位。例如,读入一行,得到一个由0和1组成的数组,然后根据这些位计算对应的十进制数。比如,第一位是最高位,第二位次之,以此类推。所以计算的时候,每一位对应的权是2的相应次方。比如,第0位(假设索引从0开始)是最高位,对应的权是2^29,因为总共有30位。比如,二进制数的各位是b0, b1, ..., b29,那么对应的数值是sum_{i=0到29} b_i * 2^(29 -i)。或者等一下,输入的30位是按从高位到低位的顺序排列的,所以例如,第一个数字是最高位(比如二进制数的左边第一位),所以比如,二进制字符串是b0 b1 ... b29,那么对应的数值是b0 * 2^29 + b1 *2^28 + ... + b29*2^0。所以需要将输入的每一位依次处理,每位乘对应的权,然后累加总和。 那如何处理输入呢?每行有30个0或1,用空格分隔。可以用一个循环读取每个数字,然后计算总和。比如,对于第i个数字(从0开始),对应的权是2的(29 - i)次方?因为第一个数字是最高位,所以权是最大的。例如,30位的话,第一位是最高位,权是2^29,第二位是2^28,依此类推,最后一位是2^0。所以循环每个输入的数字,乘以对应的权,累加到总和即可。 那具体来说,对于每个幸运符的二进制数,我们可以预先计算出对应的十进制数值,并保存下来。然后,对于每个查询x,遍历所有幸运符的十进制数值,检查该数值是否包含x。这里需要注意的是x是一个一位的十进制数字,所以可能的值是0-9中的一个。比如,当x是0时,要检查十进制数中是否有0的存在。例如,数值10包含0,数值0也包含0。其他数字类似。 所以,问题转化为如何将一个十进制数转换为字符串,然后检查是否包含x的字符形式。例如,将数值转换为字符串,然后判断是否存在字符x对应的字符。例如,x是5,那么字符串里是否有'5'。 但是,如何处理数值0的情况?比如,当输入的二进制全是0,那么数值是0,转换为字符串是"0",这时候包含0。其他情况,例如数值是5,转换为字符串是"5",包含5。数值是10的话,字符串是"10",包含0吗?是的,题目中的例子说明,十进制数0包含0,其他数的前导零被忽略,但中间的零会被算上。例如,数值10的十进制字符串是"10",里面有1和0,所以当x是0时,这个数是符合条件的。 所以,对于每个十进制数num,只要将其转换为字符串,然后判断字符串中是否包含x的字符即可。注意x是当天的查询数字,比如x=0的话,字符串中有'0'吗? 那么,步骤: 预处理阶段: 对于每个编号i(1到n): - 读取30个0或1的数值,按顺序组成二进制数,转换成十进制num。 - 将num转换为字符串s_num。 - 保存该字符串,或者保存每个数字对应的x是否存在的标记。 例如,可以预处理每个编号对应的各个数字是否存在。例如,对于每个编号i,预处理一个数组has_digit[10],其中has_digit[x]表示该编号的十进制数是否包含数字x。这样,当处理每个查询x时,只需要检查每个编号的has_digit[x]是否为true即可。 这样的预处理可以节省每次查询的时间。因为对于每个查询x,只需要遍历所有编号,检查has_digit[x]是否为真。这样预处理的时间是O(n*10),而每次查询的时间是O(n),这在n=1000,t=10000的情况下,总的复杂度是1e4 * 1e3 = 1e7,这应该是可以接受的。 所以,这种预处理方法是可行的。具体来说,预处理每个编号的十进制字符串,然后记录每个数字是否出现。例如,对每个编号i的十进制字符串s,遍历每个字符,将对应的has_digit数组设为true。 这样,每个查询x,只需要遍历所有编号i,查看has_digit[x]是否为真,并收集符合条件的i,排序后输出。 那具体如何实现呢? 步骤: 1. 输入n和t。 2. 预处理每个编号的二进制转换为十进制数值,并转换为字符串,然后记录每个数字的出现情况。 例如,对于每个编号i(从1到n): a. 读取30个0或1的数字,保存到一个数组或者直接处理。 b. 计算对应的十进制数值num。 c. 将num转换为字符串s。 d. 创建一个长度为10的bool数组,初始化为false。然后遍历s中的每个字符c,将对应的数字位置设为true。例如,c是'5',那么has_digit[5]=true。 e. 保存这个has_digit数组,或者可以保存一个数组的数组,比如对于每个i,保存一个数组,其中每个元素表示是否存在对应的数字。 3. 处理t次查询,每次查询给出x: a. 遍历所有i(1到n),检查该i的has_digit数组中x是否为true。 b. 收集所有符合条件的i,排序后输出。 现在,问题转化为如何高效处理这些步骤。 对于步骤2中的二进制转十进制,需要注意的是,输入的每个二进制数的30位是按从高位到低位的顺序排列的。比如,第一位是最高位,所以对应的权是2^29,第二位是2^28,直到最后一位是2^0。例如,二进制数1 0 0 ... 0(共30位)对应的十进制是2^29。 所以,如何计算这个数值? 例如,每行的输入是30个0或1的整数,用空格分隔。可以用循环读取每个位,并计算对应的权值总和。 例如,初始sum=0。然后,对于第j位(从0到29),输入的数值是bit,则sum += bit * (1 << (29 - j))。例如,第一个bit对应的是2^29的权,第二个是2^28,依此类推。 例如,假设输入的数组是bits[0...29],其中bits[0]是最高位,那么sum = sum_{j=0到29} bits[j] * (1 << (29 -j))。 这样,就可以正确计算对应的十进制数值。例如,对于二进制数"101",如果输入是1 0 1,那么对应的权是: 位0:1 << 2 =4 → 1*4=4 位1:0 <<1=0 →0 位2:1<<0=1 →1 →总和4+1=5。对吧?因为总共有三位的话,假设题目中的情况是30位,那么每个位的权是相应的。 所以,这样计算是正确的。那么在代码中,如何处理呢? 在C++中,可以读入每个位的值,然后循环处理每个位,累加它们的权值。 例如,对于每个幸运符i: unsigned int num = 0; for (int j=0; j<30; j++){ int bit; cin >> bit; num += bit * (1 << (29 - j)); } 这里需要注意的是,当30位都为1时,num的值是2^30 -1,也就是1073741823,这在unsigned int中是可以保存的。所以num的类型可以是unsigned int,或者用更大的类型,比如unsigned long long。但题目中的数值范围可能更大吗?30位的二进制数最大是2^30 -1,即大约1e9,这在unsigned int的范围内(unsigned int最大是4e9左右),所以没问题。 那计算完num之后,需要将它转换为字符串。例如,用to_string(num)函数,得到其十进制表示的字符串。然后,遍历每个字符,记录哪些数字出现过。 例如,字符串s = to_string(num); 然后,初始化一个bool数组has_digit[10] = {false}; 然后,遍历s中的每个字符c: for (char c : s) { int d = c - '0'; has_digit[d] = true; } 这样,对于每个幸运符i,保存has_digit数组。但如何保存呢?可以用一个二维数组,比如vector<array<bool,10>> digits(n+1); 因为编号是1到n,所以索引从1到n。digits[i][x]表示编号i是否包含数字x。 这样,预处理阶段完成后,每个查询x的处理就可以快速完成。 然后,对于每个查询x,遍历所有i,收集digits[i][x]为true的i,排序后输出。 现在,分析时间复杂度: 预处理阶段,每个幸运符的处理是O(30)时间(读入30位)加上O(L)的时间,其中L是十进制数的位数。对于最大的数1e9来说,L是10位,所以每个幸运符的预处理是O(30+10)=O(40)时间。总共有n个幸运符,所以预处理的总时间是O(n*40)。n最大是1000,所以是4e4次操作。 查询阶段,每个查询需要遍历n个幸运符,检查digits[i][x]是否为true。n是1000,每个查询是O(n)时间。总共有t=1e4次查询,总时间是1e4 * 1e3 = 1e7次操作。这在C++中是可以通过的。 所以,这样的算法是可行的。 现在,具体到代码实现: 步骤: 1. 输入n和t。 2. 对于每个i(1到n): a. 读取30个整数,每个是0或1。 b. 计算num的值。 c. 将num转换为字符串s。 d. 初始化一个长度为10的数组,初始为false。 e. 遍历s中的每个字符,将对应的数字设为true。 f. 保存该数组到digits[i]。 3. 处理t次查询: a. 输入x。 b. 遍历1到n的i,收集digits[i][x]为true的i。 c. 将这些i排序。 d. 输出用空格分隔的编号,或者空行。 现在,代码的细节问题: 如何存储digits数组?可以用一个二维数组,比如vector<vector<bool>> digits(n+1, vector<bool>(10, false))。因为编号从1到n,所以digits的大小是n+1,索引0未被使用。每个digits[i]是一个vector<bool>,长度为10。 读入每个幸运符的二进制位时,需要注意输入的数据。比如,每行有30个整数,用空格分隔。可以用循环读取。 例如: for (int i = 1; i <= n; ++i) { unsigned int num = 0; for (int j = 0; j < 30; ++j) { int bit; cin >> bit; num += bit * (1 << (29 - j)); } string s = to_string(num); vector<bool> &has_digit = digits[i]; for (char c : s) { int d = c - '0'; has_digit[d] = true; } } 这样,每个i对应的has_digit数组就被正确填充。 处理查询时,例如: for (int day = 0; day < t; ++day) { int x; cin >> x; vector<int> res; for (int i = 1; i <= n; ++i) { if (digits[i][x]) { res.push_back(i); } } sort(res.begin(), res.end()); if (res.empty()) { cout << "\n"; } else { for (int i = 0; i < res.size(); ++i) { if (i > 0) cout << " "; cout << res[i]; } cout << "\n"; } } 但是,这里有一个特殊情况需要注意:当x是0的时候,数值0的情况是否被正确处理? 例如,二进制全为0的30位,转换成十进制是0。此时,s是"0",所以has_digit[0]会被设为true。所以,当查询x=0时,这个编号会被选中。其他情况,例如数值为10的话,s是"10",所以0会被记录。因此,这种处理是正确的。 另一个问题,输入的二进制数可能有前导零吗?比如,输入的二进制位可能有前导零,但转换成十进制的时候,前导零会被忽略吗?例如,输入的二进制是30位,前k位是0,后面的位构成某个数。例如,输入的二进制是30个0,对应的十进制是0,所以转换成字符串是"0",这时候包含0。而如果输入的二进制是前导零,但后面有1,例如,前29位是0,最后一位是1,那么对应的十进制是1,字符串是"1",所以不包含0。所以,在预处理的时候,前导零已经被正确处理,因为转换成十进制的时候,数值是1,所以字符串中没有前导零。所以,题目的要求是满足的。 所以,这样的处理是正确的。 现在,代码的编写应该没有问题。需要注意的地方: 1. 输入的二进制位可能很大,但使用unsigned int足够吗?假设在编译器中,unsigned int是32位的话,那么可以容纳30位的二进制数。例如,30位全1是2^30 -1=1,073,741,823,这在unsigned int(范围0到4,294,967,295)中是足够的。所以没问题。但若环境中的int是16位的,则可能不够。不过,题目中的测试数据应该不会让这种情况出现。为了保险,可以使用unsigned long long,虽然在这种情况下并不需要,但这样更安全。 或者,可以将num的类型改为unsigned long long。例如: unsigned long long num = 0; 这样,可以处理更大的数值。但对于题目中的情况,30位的二进制数,这样处理没有问题。 所以,在代码中将num的类型设为unsigned long long更好。 例如: unsigned long long num = 0; for (int j = 0; j < 30; ++j) { int bit; cin >> bit; num += (unsigned long long)bit * (1ULL << (29 - j)); } 这样,无论bit是0还是1,乘以对应的权值都不会溢出。例如,当j=0时,1ULL <<29是正确计算的。 这样,计算num的正确性更高。所以,在代码中应该使用unsigned long long类型。 另外,注意左移运算符的位数是否正确。例如,当j=0时,对应的权是2^29,所以1<<29。此时,当j=0时,29-j=29-0=29,所以是正确的。 是的,所以num的计算是正确的。 综上所述,这个方案是正确的,可以解决问题。现在,将代码写出来即可。</think>为了高效解决这个问题,我们需要预处理每个幸运符的二进制编码转换为十进制数,并记录其包含的数字。然后根据每天的查询快速检索符合条件的编号。 ```cpp #include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, t; cin >> n >> t; vector<vector<bool>> digits(n + 1, vector<bool>(10, false)); for (int i = 1; i <= n; ++i) { unsigned long long num = 0; for (int j = 0; j < 30; ++j) { int bit; cin >> bit; num += (unsigned long long)bit * (1ULL << (29 - j)); } string s = to_string(num); for (char c : s) { int d = c - '0'; digits[i][d] = true; } } while (t--) { int x; cin >> x; vector<int> res; for (int i = 1; i <= n; ++i) { if (digits[i][x]) { res.push_back(i); } } sort(res.begin(), res.end()); for (size_t j = 0; j < res.size(); ++j) { if (j > 0) cout << " "; cout << res[j]; } cout << "\n"; } return 0; } ``` **解释**: 1. **输入处理**:首先读取n个30位二进制数,将它们转换为十进制数值。 2. **预处理**:对每个幸运符的十进制数值转换为字符串,并记录每个数字的出现情况。 3. **查询处理**:对于每个查询x,遍历所有预处理过的幸运符,快速判断是否包含目标数字,收集结果后排序输出。 **关键点**: - 使用`unsigned long long`确保大数转换的正确性。 - 预处理阶段将每个编号的十进制数字存在性记录为布尔数组,加速查询。 - 输出时注意排序要求和格式处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值