首页 > 想要在大厂生存必须要学会提效
头像
lxylxy_
发布于 02-17 10:28 广东
+ 关注

想要在大厂生存必须要学会提效

实习第二周了,这周是猛猛开发的一周,给自己排的13pd的活,下周一再开发一天的话总共8pd就能结束,比我预想的要快的多的多。再次回来做需求感觉是不一样,当把之前忘记的东西捡起来之后,开发起来好像也能实现一些比较麻烦的联动,解决问题的过程还是让自己信心大增的。这周的周记就分享一下我这周的感悟吧。

前端已死?

别担心,还没那么快死

”前端已死“。这句话从gpt3出来的时候就开始听了,在我读研的这几年一直有人说前端要死了,这给当时还没有找实习找工作的我很大的危机感,况且前几年疫情正值行情差的时候,互联网寒冬的加持让我觉得我选这条路是不是完了。这周我又一次听到了这句话,与当时不同的是我已经找到了心仪的工作,并且正在适应身份的转变,努力让自己变强。但当我身处如此优秀的公司,身边的同事业务能力和技术超强但却还是说出了这种话的时候,我还是忍不住想看一下,到底是什么工具让他发出了这般悲鸣。

凑近一看,原来是公司新开发的一款ai产品。这个同事对新出的产品都会有很强的好奇心,deepseek、cursor、前端新技术、字节新出的框架,他获取到资讯的第一时间就会去尝试使用这个工具,这可能就是成为一名优秀的工程师所必备的好奇心。回到”前端已死“这个话题,这个工具的牛逼之处在于,你丢进去一张设计稿,并向他描述你所依赖的组件库或者工具,它可以快速生成结构代码,并且使用你所指定的依赖

又快又好,这就是我周围这几位大神对他的评价。说实话,如果只是能够用三件套写出来对应的代码,我觉得不太稀奇,但现在的ai工具还原度太高了,而且可以用指定的组件库去实现。快,体现在他用几十秒的时间就能完成你半天甚至一天的工作量,细看他生成的代码,其中的大部分代码都是可以直接使用的,如果直接用这个工具去还原设计稿,真的可以提升不知道多少倍的效率。好,体现在他所生成的代码质量之高,结构合理,组件、函数可复用性强,没有什么多余的重复的代码,质量真的很高,很多地方的设计让周边的同事都说真的比不过他。”如果未来前端只是丢个设计稿进去,再文字限定描述一下,那你和大专有什么区别?打字谁不会呢“,一句话让大家都破防了。

我属于比较乐观的人,我觉得想让ai真的代替前端还有很多年的路要走,暂时还没有那么强的危机感,我觉得前端死是死不了的。以下几个点:1.当前的ai只能做到还原设计稿,但是当你的结构复杂,甚至涉及到动画的时候,ai还是无能为力(身边的高手都很难搞定,ai更难吧),没有足够的训练语料,也无法理解具体业务场景;2.当前的ai工具是没有办法帮你实现交互和联动逻辑的,他能做的是搭积木,搭的又快又好,但是积木稳不稳,怎么设计积木最后的展现效果还是靠人;3.bug还是存在的,人的存在就是为了解决问题的,但是机器设计的代码如果有逻辑bug,很多时候越改越错,用过ai工具解力扣题的应该深有体会,咋改都有问题。人之所以为人,就是因为人的灵活性和解决问题的能力,是因为人有机器代替不了的点,学会使用工具比担心被工具淘汰要有用的多

生存的前提是提效

人和动物最大的差别就是会不会使用工具,人与人之间最大的差别就是能不能更好的使用工具

这周最大的体会就是,一定要学会提高自己的效率,当你身边的人效率都很高的时候,你的效率低下势必会拖慢整个需求的进度,并且当你逐渐不再是新人的时候,你的需求排期一定是会被压缩的,这也意味着你的开发效率也得变得又快又好。暑期实习的时候一个需求排一个月的开发周期给我,现在这个需求排了13天,后面可能真就只有个位数的开发时间了。本周周会又听ld说要推行单周迭代,不知道可能6到7pd的任务会不会被压到5pd,如果会的话,提效真的很关键。

我跟带我的兄弟学到了好多小技巧,相比起来我真的啥都不懂啊,好像个乡巴佬。分享给大家,有时间可以去研究一下:

1.vscode的ai插件。豆包有个marscode插件,我的使用过程一遍又一遍刷新我的认知。首先是自动代码补全,上下文相似代码,常用的组件和属性,循环遍历等等,这个插件可以根据你当前的使用场景自动帮你补全代码,我这段时间感觉他至少帮我提升了1.5倍的开发效率。除了补全以外,你还可以随时在侧边问答,相当于直接在vscode中使用豆包,比如你哪个字段英文不会了,不需要打开浏览器再去查,直接丢到侧边栏的问答框就行;代码或者数据有问题,丢进去问他怎么改;需要用到mock数据,直接让他根据idl结构帮你生成,这些是真正能够大幅提高你的开发效率的,避免了很多无用时间的浪费。当我以为到此我已经掌握了他的功能时,我的同事告诉我,你还是要善于使用ai,我在定义类型的时候一般都是手动定义的,而他直接在代码中写注释:”# 帮忙根据xxx组件的需要生成类型“,竟然就可以直接在代码中生成interface或者type,再一次震惊我。到底还有多少隐藏功能等我发现。

2.一些能够提效的插件,这些看起来不太重要的东西实则会减少很多隐形的无用功。亲测好用:

  • err lens:在代码中直接高亮error或者warning等错误提示,不需要再移动光标到对应红色波浪线上去看tooltip。效果如下:

  • oh my zsh:除了可以更换终端主题以外,还内置了很多zsh插件,其中就有git指令简写,这个真的很方便,常用的几个简写:git add .->ga . git commit -m ->gc -m git push->gp 少打多少字儿
  • zsh-syntax-highlighting:配套上面使用,指令合法性提示,合法指令是绿色,不合法的是红色,比如没有安装pnpm,在你打出pnpm之后终端的字就是红的,证明你没安装,这就省去了打完指令运行后再看报错才知道没有安装某个包的时间。

3.开发效率要快,组件的基本属性和用法得记在脑子里。当在写代码时看到设计稿就知道哪些组件怎么写而不需要去经常翻阅官方文档时,会节约大量的开发时间。目前我对很多属性不熟,有时候也不知道某个样式或者功能这个组件是不是支持,大量的时间都用来看组件库官网了,太浪费时间了,感觉这些时间节约下来,又能空出1pd。

有意识的提高你的代码质量

努力避免不知道自己不知道,努力做到不知道自己知道

”你在干啥,你咋这个样子写代码啊,你这个样子写代码会被骂的。“这段时间问问题的时候听到最多的话,不过我倒是不觉得有啥不开心的,我反而觉得挺好,肯跟我说这话的同事跟我关系很好,而且能力很强,每次骂我的时候我就能学到东西了。

先来看两个例子:

1. 组件渲染:

const FormTest = () =>{
	return (
		<Form>
			<Select field="a" options={optsA} title={titleA}/>
			<Select field="b" options={optsB} title={titleC}/>
			<Select field="c" options={optsC} title={titleC}/>
		</Form>
	)
}

上面这种写法也是简单易懂,渲染三个Select组件,field,options,title不同,直接写组件当然没问题,但是不知道大家发现一个问题没,重复性很高。改成下面这样:

const FormTest = () =>{
	const selectItems = [{
		field: "a",
		options: [],
		title: "titleA"
	},{
		field: "b",
		options: [],
		title: "titleB"
	},{
		field: "c",
		options: [],
		title: "titleC"
	}]
	return (
		<Form>
			{selectItems.map(item => ({
				<Select field={item.field} options={item.options} title={item.title}/>
			}))}

		</Form>
	)
}

别看代码行数增加了,但是这明显可维护性变强了,当你有几十个select选项的时候,放在item里去维护你只需要维护数据,而不需要像第一种写法一样去维护结构了,这就是代码质量的提升。而且这些数据你是可以抽出去放在const.ts中的,整个代码也会更加整洁清晰。

2.组件传参:

// a.tsx
const Test = () => {
	return <SideSheet />
}

//b.tsx
const TestSideSheet = () => {
	return {
	<SideSheet>
		<TestSideSheetForm />  
		<TestSideSheetTable />  
	</SideSheet>
	}
}

上面的结构大概可以描述我最近做的一个组件的结构,点击页面按钮弹出侧边栏,侧边栏左边的form填完后会去请求出右边table的数据,并且table的数据需要能够被选中某几行并保留。保留后再打开侧边栏需要能够按需回显选中的数据或者所有的数据,并在页面中保留被选中的样式。大家可以想一下如果要存这些数据,需要怎么哪些状态,需要放在哪一层?

在写逻辑的时候,我认为是需要四个状态,allDataTmp,filteredDataTmp,allData,filteredData。分别代表请求回来的所有数据,被选中的所有数据,按下保存按钮后保留下来的所有数据,按下保存按钮后保留下来的被过滤的数据。由于业务逻辑的需要,这些数据需要被存在TestSideSheet组件的外面。一开始的设计思路是这样的:

// a.tsx
const Test = () => {
  	const [allDataTmp, setAllDataTmp] = useState([]),
	const [filteredDataTmp, setFilteredDataTmp] = useState([])
	const [allData, setAllData] = useState([]),
	const [filteredData, setFilteredData] = useState([])
	return (
	  	<TestSideSheet
	  		allDataTmp={allDataTmp} 
  			setAllDataTmp={setAllDataTmp}
  			filteredDataTmp={filteredDataTmp}
  			setFilteredDataTmp={setFilteredDataTmp}
			allData={allData}
  			setAllData={setAllData}
  			filteredData={filteredData}
  			setFilteredData={setFilteredData}
  		/>  
	}
}

//b.tsx
interface TestSideSheetProps extendx SideSheetProps {
	allDataTmp: Array<ExampleType>;
	filteredDataTmp: Array<ExampleType>;
	allData: Array<ExampleType>;
	filteredData: Array<ExampleType>;
	setAllDataTmp:(v: Array<ExampleType>)=> void;
	setFilteredDataTmp:(v: Array<ExampleType>)=> void;
	setAllData:(v: Array<ExampleType>)=> void;
	setFilteredData:(v: Array<ExampleType>)=> void;
}
const TestSideSheet = (props: TestSideSheetProps) => {
	const {xxxxx} = props  // 简写了,不然好麻烦
	return {
	<SideSheet>
		<TestSideSheetForm 
	  		allDataTmp={allDataTmp} 
  			setAllDataTmp={setAllDataTmp}
  			filteredDataTmp={filteredDataTmp}
  			setFilteredDataTmp={setFilteredDataTmp}
  		/>  
		<TestSideSheetTable 
  			allData={allData}
  			setAllData={setAllData}
  			filteredData={filteredData}
  			setFilteredData={setFilteredData}
  		/>  
	</SideSheet>
	}
}

看着恶心不,我也觉得恶心,但是当时我的想法是先实现功能,再去优化,所以我先按照这个去做了。问题就在于,当你变量名字起的也很垃圾还有一堆状态的时候,有时候你自己都不知道要用哪个状态,要保留哪个了。再接着,好不容易完成基本功能后,发现有bug,那些原本以为不需要传的参数突然发现必须要传进来才行,你一个组件需要定义怎样恶心的props结构才能去完成??受不了了于是乎改一下,这里也有一个点,善用工具,不仅仅是ai,还有ahooks和lodash等等

// a.tsx
const Test = () => {
  	const [tableState, setTableState] = useSetState({
		allDataTmp: [],
	  	allData: [],
	  	filteredDataTmp: [],
	  	filteredData: []
	})
	return (
	  	<TestSideSheet
	  		tableState={tableState}
			setTableState={setTableState}
  		/>  
	}
}

// b.tsx
interface TableState {
  		allDataTmp: Array<ExampleType>;
		allData: Array<ExampleType>;
		filteredData: Array<ExampleType>;
		filteredDataTmp: Array<ExampleType>;
}
interface TestSideSheetProps extendx SideSheetProps {
	tableState: TableState;
	setTableState: (v: Partial<TableState>) => void;
}
const TestSideSheet = (props:TestSideSheetProps) => {
	const {tableState, setTableState} = TestSideSheetProps
	return {
	<SideSheet>
		<TestSideSheetForm 
			tableState={tableState}
  			setTableState={setTableState}
  		/>  
		<TestSideSheetTable 
			tableState={tableState}
  			setTableState={setTableState}
  		/>  
	</SideSheet>
	}
}

看着爽多了吧,这样不仅清晰,所有的state设定都通过setTableState操作就完事了,简单方便高效,并且后面别人在改你的屎山的时候至少可以知道你这些变量是啥,从哪来的。

这段时间对于提高代码质量的思考如下:

  1. 文件、变量命名要与业务和功能相关,如果与业务无关,那么其他人在改代码时就会需要花时间去找你这个结构对应的是哪块。如果与功能无关,那更是麻烦,自己写着写着可能都不知道是啥了,所以命名是个学问;
  2. 要考虑后人足够的可复用性,包括是否受控,包括放在那一层级去定义,引入之后的改动成本等等;
  3. 要在开发过程中不段打磨自己的代码结构。一开始你的设计可能是一个版本,当你写着写着发现这些结构好像太过繁琐,可能就需要重新组织一下了;
  4. 当你定义了一堆状态要去维护,那应该会有更简单的方法,试着优化一下;
  5. 当你觉得一块功能很重,放在某个地方不顺眼,试着优化一下,抽出去单独维护或者考虑一下更好的设计。

最后的话不知道大家知不知道知识四象限,我第一次听就觉得挺有道理的。四象限分别是知道自己知道,不知道自己知道,知道自己不知道,不知道自己不知道。我目前总是有知道自己不知道的感觉出现,所以要针对不知道的东西去学习,而大家应该努力的方向就是努力避免不知道自己不知道,努力做到不知道自己知道。大家共勉!

以上是本周的一些感悟。很感谢大家能够看到现在。大半夜写了一堆思考,感觉阶段性总结对自己还是蛮重要的,希望这些思考也能引起大家的共鸣吧,一起加油!

全部评论

(10) 回帖
加载中...
话题 回帖