作者 | 可可
责编 | 仲培艺
本文经授权转自开发者技术前线(ID:TamicThinking)
最近爆出多个大公司外包被内部员工秀优越感的事情,到底是什么事呢,就是貌似一个外包吃了公司的下午茶,就被 HR 当场怒斥,所以不得不让人思考,甚至对所有外包和内部员工说一些我的事情。
上个月,读者发来一段话:”我看到有几个和我一样做外包的同行,有说自己在甲方公司不受尊重,决定离职。 “卧槽,现在职场都开玩阶级了!”
外包被职场歧视
前几天外包女员工在职场论坛留言,事情是这样的:
她说自己被外派到一家大公司上班,因为那家公司是大公司,在休息的时候还提供零食和下午茶。大家都知道女生爱吃,有回这个外包的女员工就吃了一些公司的零食。结果当天就收到那家公司领导的信息,说她是外包员工,不是正式员工,麻烦不要随便偷吃公司零食。并且还要她注意自己素质。
失足进入外包
这位读者也是经历过外包的,下面他说出了自己的经历:
“我 15 年从本科毕业,错过了移动互联网最好的时期,当时自己由于刚毕业,经验不足加上自己年轻,面了几家公司,最后拿了某三线公司的 Offer,还有一个 BAT 某场的外包 Offer。
当初面试时,面试官也对我承诺过,一年后优秀可以转正,我也怀着一颗大厂梦,进了某软,去了某 A 外包。
当初去的某大厂做外包,进去很开心,看着顶级的知名互联网公司,进去锻炼。
很多人对于外包工作,总是会带有一些偏见,认为我们外包的员工,要么是能力差,要么就是学历低,这种现象在互联网行业相当多。对于很多大公司来说,有些业务一般都会外包出去,因此很多人都有过外包的经历。
感觉像犯罪了一样对待,但其实外包的员工能力并不一定差,甚至有时候比那些正式员工更优秀,更上进。
但从另一方面来说,虽然和正式员工做了相同的工作,但是我们外包员工的待遇却千差万别。不管是工资还是待遇,都要比正式员工低很多。“
昨天,他告知我自己去了腾讯某核心部门,拿到了 3.1 级别的 Offer——恭喜!
只能说太 6 了。
目前大型的外包公司有东软、中软国际、软通动力、文思海辉、博彦等。
采访华为外包:“目前对这市场不抱有多大期望”
我专门对一名做了 4 年外包的同行做了一次采访,他说道:
”目前对这市场不抱有多大期望,至少外包算是非常正规,不怎么加班。不过水也深,有好项目和差项目。
好项目的流程正规,前途明朗,平行项目组沟通顺畅,管理经验和架构能力都能得到提升;
差项目累得跟牛一样,领导只知道堆功能,开发质量和进度都无法正常保证,项目总结以后总有人莫名背锅。
大公司的外包都是封闭性的,很难接触外网,申请外网权限麻烦不说,也不是每个人都能开,大多数人都是手机查资料,对网络的依赖没那么大,上班时聊 QQ、微信的人不多,效率上来说算是比较高的。
因为版权问题,大公司外包使用类库的时候需要鉴别类库是否完全开源,不然不予考虑,尽量让我们原生开发。
一些大项目会考虑从别的大公司或者国外请团队过来主导或者协助开发架构(如插件化开发框架),完事后内部进行消化,扩展以及维护。
外包气氛得靠运气了,有的项目组死气沉沉,有的项目组非常活跃,不是每个甲方领导都不敢说话,主要看运气,也看自己的处世方式。“
什么是外包?
说了以上事情原委和外包同学的思考,给大家看看什么是外包。
人事外包,指企业将人事行政管理的大部分工作(通常是建立劳动关系、录用退工手续、档案管理、保险福利管理、工资发放等),以协议方式交由专门的人力资源外包服务商完成。
人事外包分为人事代理和劳务派遣。区分两者的关键点,在于谁同员工签订劳动合同。人事代理是员工与用人单位建立劳动关系,企业只是将人力资源非核心部分的工作,部分或全部委托专业机构代理;而劳务派遣则是中介机构成为员工的法定雇主,实际用人单位同中介机构签订人才派遣或租赁合同,用人单位只负责派遣员工的工作管理,人事管理则交由中介机构来做。
为什么不建议去外包?
在外包公司严重没有归属感,就类似上面的某些公司,还不让吃零食。
几乎每天都是做着重复的工作,对于自身技术没有本质上的提高。大多被内部员工使唤来使唤去。
想学点技术,根本稳定不下来,这段时间这个项目,再过一段时间又是另外一个项目,毫无连续性。
福利几乎没有,没有地位,更没有话语权。
开年会都是内部去参见,外包留下来加班改 Bug。
如果你目前在外包的坑,请赶快远离,不然过几年后你会发现,现在的工作经历几乎给你带去的加分机会为 0 甚至是负数。
如果是在 BAT 外包,建议学一年的流程和技术,赶快跳坑吧,时间越久,你越没竞争力。
以前外包是求职跳槽时会被歧视,现在都变成了职场赤裸裸的歧视,我只想说,外包没抢没偷,为何就不当人看。
总结
从公司角度说,外包员工的成本都含在外包合同里,确实不应该再占有其他公司福利。
从员工角度说,福利零食值几个钱?何苦为难。
从截图角度说,这句提醒确实不尊重人。
作者 : 可可, 专业三年新媒体运营。
声明:本文经授权转载自开发者技术前线,如需转载请联系原作者。
开发者技术前线 ,汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。
2019年程序员应该认真学习的技术语言!
热 文 推 荐
☞ 搜狗员工吐槽“统计加班时长裁人”,CEO 王小川破口大骂:“赶快滚”
☞ 身为程序员的父母,你年薪多少才能让“码二代” 不输在起跑线上
☞ 何恺明的GN之后,权重标准化新方法能超越GN、BN吗? | 技术头条
☞ EOS现状: 72%应用涉赌被列为高危, 说好的诗和远方, 你竟沦落成了这样?
System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"
你点的每个“在看”,我都认真当成了喜欢



单例模式中的隐藏陷阱:你真的了解单例吗?
引言
单例模式是日常开发中较常用的一种设计模式,它能够确保一个类只有一个实例,并提供一个全局访问入口。
在之前的开发过程中,观察到进程退出时偶现 crash
现象。由于该问题仅发生在生命周期末端且未影响核心功能,并未深入排查原因。
近期看到技术公众号分析单例模式潜在问题的,意识到此前的crash
大致就是因此导致的。
场景列举
问题
先看代码,看看执行会发生什么?
main
函数
- 首先获取
SingletonB
的实例。 - 然后获取
SingletonA
的实例。 - 最后输出退出信息。
c++ 代码解读复制代码int main() {
SingletonA::getInstance();
SingletonB::getInstance();
std::cout << "exe exit!" << std::endl;
return 0;
}
单例类 SingletonB
SingletonB
类使用静态局部变量instance
来确保只有一个实例。- 构造函数中,
mpBuf
分配了内存,并将字符串"hello"
复制到该内存中。 - 析构函数中,释放了
mpBuf
所占用的内存,并置为nullptr
。
c++ 代码解读复制代码// 单例B
class SingletonB {
public:
~SingletonB() {
std::cout << "SingletonB destroyed." << std::endl;
delete []mpBuf; // 回收资源
mpBuf = nullptr;
}
static SingletonB* getInstance() {
static SingletonB instance;
return &instance;
}
void doSomething() {
printf("mpBuf[0] = %c\n", mpBuf[0]);
}
private:
SingletonB() {
std::cout << "SingletonB created." << std::endl;
mpBuf = new (std::nothrow) char[10]; // 创建资源
memcpy(mpBuf, "hello", 5);
mpBuf[5] = '\0';
}
private:
char *mpBuf;
};
单例类 SingletonA
SingletonA
类同样使用静态局部变量instance
来确保只有一个实例。- 构造函数中,简单输出创建信息。
- 析构函数中,调用
SingletonB
的doSomething
接口。
cpp 代码解读复制代码// 单例A
class SingletonA {
private:
SingletonA() {
std::cout << "SingletonA created." << std::endl;
}
~SingletonA() {
std::cout << "SingletonA destroy begin. call A" << std::endl;
SingletonB::getInstance()->doSomething();
std::cout << "SingletonA destroyed end." << std::endl;
}
public:
static SingletonA* getInstance() {
static SingletonA instance;
return &instance;
}
};
输出
程序在退出时,发生crash
了。
c++代码解读复制代码$ ./a.out SingletonA created. SingletonB created. exe exit! SingletonB destroyed. SingletonA destroy begin. call A Segmentation fault
代码分析
上述的实现,很明显可以看出因为调用了已析构的对象,导致异常crash
。
但是在实际项目开发过程中,单例模式的调用分散在各个文件中,由于初始化顺序难以控制,很容易出现调用已析构对象的情况,进而导致程序崩溃。这类问题一旦发生,往往难以迅速定位和解决。
看看AI怎么评价这段代码:
c++ 代码解读复制代码Me: 魔镜啊魔镜,上述代码有什么问题?
魔镜:来了,老弟!这代码毛病可不小呐~
那 `SingletonA` 析构的时候,还跑去调用 `SingletonB` 的方法。
程序结束的时候,静态对象是后构造的先析构,这 SingletonB 不妥妥先析构了,mpBuf也回收了。
SingletonA 再去调用 SingletonB::doSomething,指定下机啊!
哪个损粗写的这代码呐!回炉重造吧,赶紧的啊~
Me: 乡村爱情看多了吧你,口音听的上头。
正经点,那怎么规避这类问题?
魔镜:闲来无事,网上爬了几集,真好看~
有很多种方式可以避免这种问题,我就说两种,好好听,好好学!
① 避免单例对象析构,如下写法:
SingletonA* SingletonA::getInstance() {
static SingletonA *instance = new (std::nothorw) SingletonA();
return instance;
}
② 增加全局变量,检测对象是否析构。每次获取实例时,特别是析构中获取单例时,先判空。
static std::atomic<bool> gObjAlive(true);
SingletonA::~SingletonA() {
gObjAlive = false;
}
SingletonA* SingletonA::getInstance() {
if (!gObjAlive) {
return nullptr;
}
static SingletonA instance;
return &instance;
}
通过与AI
的友好沟通,规避的方案有很多。上述的两种方案,各有利弊:
- 第一种方案
优点:写法简洁。
缺点:由于不会调用析构函数,除内存会随进程退出释放外,析构函数中涉及的硬件资源释放等操作无法执行,可能引发潜在问题。 - 第二种方案
优点:安全性较高,可自动释放所持资源。
缺点:用时不够便捷,每次调用单例对象(尤其是在析构阶段)都需要进行判空操作。
总结
- 结合全文,
crash
的问题根源在于单例析构函数中调用其他单例对象的接口。
进程退出阶段,全局单例对象的析构顺序未明确,可能导致调用了已释放的单例对象接口,引发crash
。 - 尽管可以通过控制单例调用的顺序来规避此类问题。但这种方式并非最优解,而且大型项目中难以实施。另外,程序健壮性不应依赖这种非确定性的语言特性,而应通过设计优化从根本上避免此类问题。
- 最后,代码运行的行为和结果应是可预见的,不应依赖特殊操作或非确定性行为。若有此类依赖,应是程序设计缺陷,该加以优化。
评论记录:
回复评论: