近日,2019届全国普通高校毕业生平均期望月薪出炉。
大学生期望薪资排名前三位的依次是:
北京:平均期望薪资12992元/月;
上海:平均期望薪资12070元/月;
南京:平均期望薪资9771元/月。
图片来源:羊城晚报
与应届生高期望薪资相对的是,陆续传出众多企业大裁员的消息。
这场裁员潮来的快且急,很多人措手不及:有人昨天刚通宵发布上线第二天就被裁了;有人早上还在改Bug下午就被裁了;还有公司不发工资逼着员工主动离职…...
被裁对象大多是工作一两年的、或者在公司时间较短的职场人,而这部分人又是在寒冬里找工作颇为困难的。
通过走访几位被裁的年轻程序员,笔者得知即使大家在寒冬找工作困难,但期望薪资仍是比原来的有所涨幅,理由是工作一两年了总不能被应届生吊打。
正如小动物从春天开始积累食物过冬,对于工作一两年的职场新人来说,积累,是重要且必须的。
经验积累:做好项目总结,搭建知识框架
很多码农认为,我的项目一个接一个的,连改Bug的时间都没有,怎么有时间写总结呢?
要知道我们离开公司时是不能带走代码的,有人在写简历时遇到难题:似乎没什么可写的。
再者在面试过程中常会讨论到技术细节,由于时间久远记不清细节,许多人尴尬地说“我忘了”。
这是日常从不复盘总结的原因,工作一年脑袋一片空白。
曾见过有程序员边做项目边记录,踩过的坑,遇到的变更,自己犯的错误等。
工作一年后整整齐齐码了一摞项目总结和知识整理。写简历就不愁没得写了,准备面试也能快速准备起来。
面试积累:保持危机感,每半年出去面试一次
身处BAT的张辉有半年出去面试的习惯,即便当前工作稳定,待遇不错,张辉始终保持一份危机感。
张辉很现实,从不认为公司是一成不变的,个人可以安心养老。反而越是和平时期越要去面试,一是如果有更好的机会正好跳槽;二是在大公司时间长思维容易固化凝滞,去面试看看外面的形势;三是通过面试复习自身的专业知识。
张辉总结出,在涨薪或年终奖发放前去面试的效果最好,无需浪费时间等年终奖,一是下家会给承担这部分的奖金,二是给老东家挽留人涨薪的机会。
张辉工作五年,工资从不足一万到如今的3万+,每次跳槽均通过这个策略进行的。
公司越大,我们基层员工对公司的形势感知得越晚,等知道时再行动也晚了。
正如英特尔的创始人格鲁夫,对此形容道,“在行船之时,风向变了,可是却因为某些原因,比如风在高空转向,而你在地面上却丝毫没有感觉到。
突然,船倾斜了,过去适用的一切现在已经毫无帮助,又必须感受到风的新方向及其强度。此时此刻,要采取决定性的行动是非常困难的。”
资源积累:扩大圈子,增加弱连接
这次寒冬对于工作一两年的年轻职场人是个大考验:
这与招聘职位收紧,公司要求提高有关,也和初入职场,很多程序员积累的人脉资源少有关。
在同样被裁的小员工正为找工作发愁时,工作五年的李达,轻松地找到下家,他在被裁的第二天,收到学长公司的邀请,薪资待遇比前的翻一倍。这学长是李达在校友会认识的,后来和他合作过项目,他十分认可李达的能力。
除此之外,先前参加技术会议结识的技术朋友,也向李达伸出橄榄枝。
寒冬对于没有积累的人,是伤筋动骨,而对于有资源积累的人,则是破茧成蝶。
我们在闲暇时,不妨多做“无用功”来扩大弱连接:写技术博客,参加感兴趣的技术分享会,校友会认识优秀校友等。
乔布斯说过,人生就是一个连点成线的过程,有些经历也许一开始看不到它的意义所在,但也许若干年后,便会发挥其特有的作用。
对于正在找工作的人,需迅速放下被裁的愤恨心,调整情绪投入找工作中,可通过扩大求职范围,在朋友圈、校友群、技术群广发求职信息,也可询问前领导、同事是否有合适的机会。
我们无法左右市场和企业的形势变换,仅能左右我们自身的积累和选择方向。正如马云所说,在春风得意时布好局,才能四面楚歌时有条路。
作者简介:五五,白天搬砖,晚上砌梦想。相信每个人有故事,程序员更是有许多事故,书写最接地气的程序员故事。
荐号
AI科技大本营,是中国专业IT社区CSDN旗下的AI垂直媒体,致力于关注并报道全球人工智能领域技术、及产业方面的最新进展。
热 文 推 荐
☞ 公开课报名 | 基于自定义模板的OCR结果的结构化处理技术
print_r('点个赞吧');
var_dump('点个赞吧');
NSLog(@"点个赞吧!");
System.out.println("点个赞吧!");
console.log("点个赞吧!");
print("点个赞吧!");
printf("点个赞吧!\n");
cout << "点个赞吧!" << endl;
Console.WriteLine("点个赞吧!");
fmt.Println("点个赞吧!");
Response.Write("点个赞吧");
alert("点个赞吧")
echo("点个赞吧")




本章主要学习知识点
- 了解three.js中的组对象group,并练习一些基本操作
- 练习遍历模型树结构、查询模型节点
- 了解本地坐标与世界坐标概念
- 练习修改模型相对于局部坐标原点的位置
- 练习移除隐藏模型对象操作
模型建组group
在Three.js 中,模型建组是通过THREE.Group
类实现的,它可以将多个模型对象组织成一个逻辑整体,便于统一管理和操作,想象一下如果场景中的模型对象都散乱放置,那该有多恐怖~
树形结构
Three.js 场景采用树状结构,Group
继承自Object3D
,可包含任意子对象(Mesh、Light、Camera等)
js 代码解读复制代码const group = new THREE.Group();
group.add(mesh1, mesh2, light);
scene.add(group);
坐标继承
组内所有子对象使用组坐标系,当组发生变换时,子对象会跟随整体移动/旋转/缩放,通俗点说就是老大一动小弟全都要动
js 代码解读复制代码group.position.set(30, 0, 0); // 所有子对象整体右移30单位
实际操作下 ,创建2个立方体,并设置cube2沿X轴向右移动5个单位(为了区别,将cube进行自旋转)
js 代码解读复制代码cube = new THREE.Mesh( geometry, material );
cube2 = new THREE.Mesh( geometry, material)
cube2.position.x = 5;
接下来新建一个组对象,将cube和cube2放入其中编组,同时将gounp组对象沿Z轴平移5个单位,看看会发生什么
js 代码解读复制代码// 创建一个THREE.Group对象
const group = new THREE.Group();
group.add(cube,cube2)
group.translateZ(5)
scene.add(group)
从图中可发现,cube和cube2都被沿Z轴平移了5个单位,只就是老大一动小弟全都要动
尝试打印组对象下的children属性,看看有什么
js 代码解读复制代码console.log(group.children);
gounp
下包含2个mesh
,因为我们为cube和cube2两个mesh
进行了编组,但到目前为止,我们并不知道这个组叫什么,让我们来给组起个名字
js 代码解读复制代码//给组对象命名
group.name = 'cubeMeshGroup';
console.log(group);
组与组之间嵌套,形成庞大的树形结构
假设我们正在构建一个汽车模型时,就需要对每个部件进行编组,再将这些组再进行组合,最终形成一个完整的车辆, 如下是一个简单的示例
js 代码解读复制代码const car = new THREE.Group();
const chassis = new THREE.Group(); // 底盘组
const wheels = new THREE.Group(); // 车轮组
// 构建底盘
chassis.add(bodyMesh, seatMesh, steeringWheel);
// 构建车轮(子组嵌套)
const wheelFL = createWheel();
const wheelFR = createWheel();
wheels.add(wheelFL, wheelFR);
car.add(chassis, wheels);
遍历树结构
在开始遍历之前先要来了解下,树结构的基本组成
树结构的基本组成
树根
:Scene
场景对象是整个树的根节点树枝
:Group
组对象或复杂模型,可包含子对象树叶
: 单个模型、光源、相机等
好,我们先来搭建一个场景
js 代码解读复制代码const group = new THREE.Group();
group.name = '高楼';
for(let i=0; i<6; i++) {
// 创建几何体
const geometry = new THREE.BoxGeometry(1,1,1);
// 兰伯特材质
const material = new THREE.MeshLambertMaterial({color: 'deepskyblue'})
const mesh = new THREE.Mesh(geometry, material)
mesh.position.x = i*2;
group.add(mesh)
mesh.name = i+1+'号楼'; //给每个mesh对象命名
}
group.position.y = 6;
const group2 = new THREE.Group();
group2.name = '洋房'
for(let i=0; i<6; i++) {
// 创建几何体
const geometry = new THREE.BoxGeometry(1,1,1);
// 兰伯特材质
const material = new THREE.MeshLambertMaterial({color: 'deeppink'})
const mesh = new THREE.Mesh(geometry, material)
mesh.position.x = i*2;
group2.add(mesh)
mesh.name = i+1+'号楼'; //给每个mesh对象命名
}
const model = new THREE.Group();
model.name = '小区房子'
model.add( group, group2 )
scene.add(model)
这里我创建了两个组对象,分别为高楼(蓝色立方体)、洋房(红色立方体),每个组对象内部包含6个命名立方体,将这两个组对象添加到了名为小区房子的组对象中,接下来我们就可以使用three.js中内置的遍历方法进行遍历,注意我在遍历到子元素为mesh时将他们的材质颜色改为绿色
js 代码解读复制代码model.traverse(obj=> {
if(obj.isMesh) {
obj.material.color.set('green')
}
})
traverse
是一种深度优先遍历,很适合用于批量操作
深度优先遍历和广度优先遍历策略
深度优先遍历(家族长辈优先)
- 先访问父节点,再递归访问所有子节点
js 代码解读复制代码function traverse(obj) {
console.log(obj.name); // 处理当前节点
obj.children.forEach(child => traverse(child)); // 递归子节点
}
traverse(scene); // 从根节点开始遍历
适用于批量修改材质、统计对象数量等
广度优先遍历(家族同辈优先)
- 逐层访问,使用队列结构实现
js 代码解读复制代码function traverseBFS(root) {
const queue = [root]; // 初始化队列
while (queue.length > 0) {
const obj = queue.shift(); // 取出队首元素
console.log(obj.name);
queue.push(...obj.children); // 子节点入队尾
}
}
适用于快速查找最近物体、层级分析
查找某个具体的模型
通过getObjectByName
可以获取对应的模型
js 代码解读复制代码const findMesh = model.getObjectByName('1号楼')
findMesh.material.color.set('red')
找到模型后,将模型的材质改为红色,如下图所示
哦,太棒了,又学到了
本地坐标与世界坐标
我又想打比方了, 假设一个快递站有3层楼,每层楼有5个柜子
本地坐标
: 每个柜子相对于所在楼层的坐标,比如2楼第3个柜子的本地坐标是(0,0,3)
(以2楼入口为原点)世界坐标
: 整个快递站的全局坐标, 比如2楼入口的世界坐标是(0,5,0)
,那么该柜子的世界坐标就是(0,5,3)
在Three.js世界中,mesh.position
获取的是本地坐标,mesh.getWorldPosition()
获取的是世界坐标
两种坐标系之间的本质差异
特性 | 本地坐标 | 世界坐标 |
---|---|---|
参照物 | 父容器(如Group) | 场景原点(Scene原点) |
获取方式 | object.position | object.getWorldPosition() |
变化条件 | 父物体移动时自动保持相对关系 | 任何物体移动都会改变 |
应用场景 | 部件组装、相对位置调整 | 碰撞检测、全局定位 |
获取世界坐标和本地局部坐标
js 代码解读复制代码// 获取世界坐标
const worldPosition = new THREE.Vector3();
findMesh.getWorldPosition(worldPosition)
console.log(worldPosition);
// 获取本地局部坐标
const localPosition = findMesh.position;
console.log(localPosition);
获取模型的父级以及子级
js 代码解读复制代码// 获取父级
const parent = findMesh.parent
console.log(parent);
// 获取子级
const children = parent.children
console.log(children);
移除隐藏模型对象
移除模型(彻底删除)
通过 .remove()
方法将模型从场景中删除,释放内存空间。
js 代码解读复制代码//删除组对象下的cube2模型
group.remove(cube2)
注意:
- 模型被彻底删除,无法再显示。
- 如果模型有材质或几何体,需要手动调用
.dispose()
释放 GPU 内存。
隐藏模型(临时不可见)
通过 .visible
属性让模型暂时不可见,但仍存在于场景中。
js 代码解读复制代码// 隐藏cube模型
cube.visible = false;
注意:
- 模型仍在场景中,可以随时通过
model.visible = true
恢复显示 - 如果多个模型共享同一材质,设置材质
.visible
会隐藏所有关联模型
评论记录:
回复评论: