image frame

2024工作总结

     2024 年的工作汇总如下图所示,其中图中下半部分为我的主职——开发平台工作。开发平台今年的工作可以总结为这个方向:应用治理。

2024工作总结

     应用治理是相对于服务治理提出来的概念,服务治理是说,PaaS 技术平台围绕 RPC 框架提供的服务注册、服务发现、服务鉴权与限流熔断等。而应用治理,是指在开发平台层提出来的,对应用开发态、运行态、维护台进行全方位质量把关、监控管理的能力。例如下图所示的平台级健康检查与监控能力。

健康检查与监控

从头到尾说一说Java时间日期体系的前世今生

1、突击检查

     如下代码输出什么,机器当下所设定的时区为美国时区,在北京时间 2024-12-07 11:20:51 时,传入字符串“2024-12-07 11:46:36”。最终输出应该是true,还是false呢?

突击检查

2、前言

     约38亿年前地球出现生命体,约46亿年前太阳系形成,大约138亿年前宇宙大爆炸,那再往前呢?想起吕秀才对姬无命发出灵魂之问『时间是否有开端,宇宙是否有尽头』。施一公曾经在一次演讲中说,宇宙中从来不存在时间,只存在运动。地球公转太阳一圈是一年,这是运动,地球自转一圈是一天,这也是运动。从来就没有时间,或者说时间就是空间。

     『三十年春,秦晋围郑。郑伯使烛之武如秦』两千多年前我们就以时间记事,在造物主已经缔造的这一片井然有序的世界里,我们凭空创建出一个新的概念,并不断尝试融入这个世界体系–沙漏、水钟、日晷等等。今天站在计算机这个领域,也让我们重新梳理一遍,计算机世界里日期时间体系的前世今生。

3、日期从1970 年1月1日说起

     任何一个软件开发人员对这个时间应该都不陌生,有时我们忘记初始化或者忘记赋值时,日期就会显示为1970-01-01,我们也叫日期初始值。那为什么日期的初始值是从1970-01-01开始呢?有一个说法是说遵循了Unix的时间计数,Unix认为 1970年1月1日0点 [1]是时间纪元,那为什么Unix要以这个时间为准呢?

     有一处说法是说,当时操作性系统都是32位,如果每一个数值代表一秒,那么最多可以表示2^32-1,也就是2147483647秒,换算成年大概是68年。而Unix系统就是由Ken Thompson、Dennis Ritchie和Douglas McIlroy等人在贝尔实验室开发于1969年开发的,他们为了让时间尽可能的多利用起来,便用了下一年,即 1970年1月1日作为开始,然后这个约定也逐步延伸到其他各个计算机领域。

日期从1970 年1月1日说起

4、时间从GMT与UTC说起

     聊完日期我们再来看时间,爱好体育的应该都知道,看欧冠得半夜起来看,看NBA得早上起来看,现在是北京时间的14点,同时也是纽约时间的凌晨1点半。那是因为我们各地处不同时区,那时区以什么为初始划分的呢?

4.1、GMT 格林威治时间

     GMT的全称是 Greenwich Mean Time [2]即格林威治标准时间,是一种与地球自转相关、以太阳日为单位的时间标准。在十七世纪,格林威治皇家天文台为了海上霸权的扩张计划,选择了穿过英国伦敦格林威治天文台子午仪中心的一条经线作为零度参考线,也就是我们教科书上记载的本初子午线。

格林威治时间

     并约定从本初子午线起,经度每向东或者向西间隔15°,就划分一个新的时区[3],每个时区间隔1小时,在这个区域内,大家使用同样的标准时间。但各个国家也会基于各个国家的情况拆分或合并时区,比如中国横跨5个时区,但我们统一使用东八区;而美国则有东部时间、西部时间、夏威夷时间等等。

     从 1924 年开始,格林威治天文台每小时就会向全世界播报时间,最终截止到 1979 年。至于为什么会终止,自然有它的缺点和局限性,那我们就得聊聊UTC时间了。

4.2、UTC 世界协调时间

     UTC的全称是 Coordinated Universal Time [4]协调世界时间,也称世界标准时间。据说按英语的简称是CUT,按法语的简称是TUC,然后大家相互拉扯一波后,统一叫了UTC。

地球公转

     上述所说GMT时间是以地球自转与围太阳公转来计时的,GMT时间认为地球自转一圈是243600秒,而地球的运动轨迹受很多方面影响,比如潮汐摩擦、气象变化、地震及地质活动等等,运动的时间周期并不是完全规律和相同的。这样会导致其实一天并不完全是243600秒,这样平均算下来GMT的一秒就不是完全意义上最精确的一秒。但偏差通常也不会很大,基本为毫秒级偏差,但日积月累如果不加以扶正,就会越差越远。

     而UTC的计数是基于 原子钟(Atomic Clock) [5]的计数,比如铯原子钟采用铯-133原子的特性,在特定能级跃迁时会产生一个非常确定的频率9,192,631,770赫兹。然后基于铯-133原子的运动经过换算确定出我们需要的时间周期,据说这种误差可达每百万年内不到一秒。

     UTC 最终由两部分构成:原子时间与世界时间。原子时间基于原子钟,来标准化我们钟表中每一秒时间前进的数据;世界时间是结合GMT时间,我们用多少个原子时来决定一个地球日的时间长度。从1972年开始,UTC被正式采用为国际标准时间。这年实施了一种新的时间调整机制,包括使用闰秒[6]以便对齐地球自转与原子时间。

5、JDK 时间日期的发展史

5.1、java.util.Date

     说起Date那可是JDK的正牌嫡系,从1.0开始就一直存在并延续至今。但只要大家用过一些代码扫描工具,基本都是在提示你尽量不要使用Date。在oracle的官方JDK文档中,有超过一半的函数都是deprecated,要细说Date的问题,那可真是一言难尽。

java.util.Date

  • 不能单独表示日期或时间: Sat Dec 07 17:36:58 CST 2024 这是我们输出new Date()之后的数据,因为Date本质是某一个时刻的时间戳,导致它不能单独表示日期,更不能表示不带日期的时间。

  • 令人捉摸不透的API: 单就Date的方法名来看,应该是非常友好的。它提供了getYear(), getDay()等等,你但凡用过一次,一定让你抓狂。

  • 不支持时区设定: day和month是从0开始计数的,所以月最大是11,日最大是30,年输出124是因为2024年距离1900年有124年。

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
Date date = new Date();
// 输出 6
System.out.println(date.getDay());
// 输出 11
System.out.println(date.getMonth());
// 输出 124
System.out.println(date.getYear());
}
  • 不支持时区设定: 曾经写过一段这样的代码,取当前的中国时间,被老板臭骂一顿。。。Date的本质是一个时间戳。当前此时此刻,全球任何一个地方的时间戳都是同一个,Date本身不支持时区。PS.本质上这行代码也指定不了时区哦~
1
Date now = Calendar.getInstance(Locale.CHINA).getTime();
  • Date是可变的: Date是一个非常基础底层的类,但它却设计为可变。当我们计算这个data3天后是不是周末,如果程序计算中把这个date加了3天,那么你手上拿着得date也变成了3天后的日期。相比同为底层基础类的String,做得就优秀多了。
5.2、难当大任的Calendar

     JDK刚推出就发现了问题,于是赶紧在1.1版本推出了Calendar,尝试用来解决令人诟病的Date,并将Date一众函数都标记为了deprecated。但Calendar依然是可变对象、最多也只能精确到毫秒、线程不安全、API的使用复杂且笨重等等,Calendar整体而言并没有挽回颓势。

5.3、曙光来临之JSR310

     在聊JSR310之前,不得不先提一提 Joda-Time [7]这个开源Java库。Joda-Time以清晰的API、良好的时区支持、不可变性、强类型化等特性,得到了开发者社区的广泛好评,并在很多项目中被采用,被视为改善Java日期和时间处理的标杆库。Joda-Time如此优秀,Oracle也开启了收编之旅。2013年Java8发布,其中针对日期时间带来一套全新的标准规约 JSR310 [8],而JSR310的核心制作者就是Joda-Time的作者Stephen Colebourne。

JSR310

  • Instant: Instant这个单词的中文含义是『瞬间』,严格来说Java8之前的Date就应该是现在的Instant。Instant类有维护2个核心字段,当前距离时间纪元的秒数以及秒中的纳秒部分。它指代当前这个时刻,全球任一位置这一时刻都是同一时刻。这一时刻川建国同学在高床软枕打着呼,这一时刻我泡着龙井写着文稿。
1
2
3
4
5
6
7
8
9
10
/**
* The number of seconds from the epoch of 1970-01-01T00:00:00Z.
*/
private final long seconds;

/**
* The number of nanoseconds, later along the time-line, from the seconds field.
* This is always positive, and never exceeds 999,999,999.
*/
private final int nanos;
  • LocalDateTime: LocalDateTime由LocalDate和LocalTime组成,分别日期和时间,以此来解决Date中不能单独表示日期和时间的问题。它们都与时区无关,只客观代表一个无时区的时间,比如2024-12-08 13:46:21,LocalDateTime记录着它的年、月、日、时、分、秒、纳秒。但具体是北京时间的13点还是伦敦时间的13点,由上下文语境自行处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

/******************** LocalDate ********************/
/**
* The year.
*/
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;

/******************** LocalTime ********************/
/**
* The hour.
*/
private final byte hour;
/**
* The minute.
*/
private final byte minute;
/**
* The second.
*/
private final byte second;
/**
* The nanosecond.
*/
private final int nano;
  • Duration

     Duration中文含义译为『期间』,通常用来计算2个时间之前相差的周期,不得不说这一套时间JDK确实定义得语义非常清晰。

1
2
3
Instant startInstant = xxx;
Instant endInstant = xxx;
Duration.between(startInstant, endInstant).toMinutes();

     这个很好理解,比较2个时间戳时间的相差分钟数。但如果换成LocalDateTime,会是怎样呢?

1
2
3
LocalDateTime startTime = xxx;
LocalDateTime endTime = xxx;
Duration.between(startTime, endTime).toMinutes();

     因为LocalDateTime是不带时区的,所以LocalDateTime是不能直接换成成Instant的。而Duration的比较也是不带时区的,或者你可以理解它是把时间放在同一个时区进行比较,来抹去时区的影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/********************* JDK Duration.between 部分源码 *******************************/
@Override
public long until(Temporal endExclusive, TemporalUnit unit) {
LocalDateTime end = LocalDateTime.from(endExclusive);
if (unit instanceof ChronoUnit) {
if (unit.isTimeBased()) {
long amount = date.daysUntil(end.date);
if (amount == 0) {
return time.until(end.time, unit);
}
long timePart = end.time.toNanoOfDay() - time.toNanoOfDay();
if (amount > 0) {
amount--; // safe
timePart += NANOS_PER_DAY; // safe
} else {
amount++; // safe
timePart -= NANOS_PER_DAY; // safe
}
// 余下省略
}

     上述是Duration部分源码,它首先计算出2个时间相差多少天,再比较当天的时间里相差多少纳秒,再进行累加。所以你传过来2024-12-08 和 2024-12-04,那就是相差4天,至于是北京时间的12-08还是伦敦时间的12-04,在Duration里都被抹去了时区的概念。看到这里,上面的编程题里做对了吗?

  • ZonedDateTime

     真正需要使用时区,我们就需要用到ZonedDateTime。「zoned」这个单词在英汉词典中是zone的过去分时,译为『划为区域的』。

1
2
3
4
// 输出:2024-12-08T14:18:32.554144+08:00[Asia/Shanghai]
ZonedDateTime defaultZoneTime = ZonedDateTime.now(); // 默认时区
// 输出:2024-12-08T01:18:32.560931-05:00[America/New_York]
ZonedDateTime usZoneTime = ZonedDateTime.now(ZoneId.of("America/New_York")); // 用指定时区获取当前时间

     因为LocalDateTime是没有时区的,如果我们需要将LocalDateTime转成ZonedDateTime,就需要带上时区信息。

1
2
3
LocalDateTime localDateTime = LocalDateTime.of(2024, 12, 8, 14, 21, 17);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
ZonedDateTime usZonedDateTime = localDateTime.atZone(ZoneId.of("America/New_York"));

     随着JDK不断地发布演进,Time模块确实得到了质的提升,这里不一一细说Java日期时间相关API。如果你还在苦于对Date做各种Utils的花式包装,请拥抱java.time吧。

6、时间日期引起的惨案

6.1、夏令时与冬令时

     曾经小A做了一个鉴权系统,用于对请求做加密解密,保证每一次都是真实合法有效的接口请求。其中做了一个判定,如果请求的时间距现在已经超过10分钟,就会拒绝该次请求。从逻辑上来说,这很合理,但问题的雪崩却出现在3月的那个晚上。。。

夏令时与冬令时

  • 什么是夏令时

     夏令时[9]又称夏时制,英文原文为Daylight Saving Time,从名字上可以看出,夏令时诞生的背景是为了更好的利用白天的时间。夏令时概念的提出最早可以追溯到1895年,新西兰昆虫学家乔治·哈德逊向惠灵顿哲学学会提出,提前2小时的日光节约提案,以此在工作结束后,可以获得多出一段的白昼时间。

     具体夏令时的实施,以美国为例,美国会在每年3月的第二个星期日的凌晨2:00,时钟会往前调1个小时变为3:00。再在每年11月的第一个星期日的凌晨2:00,将时钟在往后调1个小时变成1:00,此时的回拨也被称为“冬令时”。

  • 夏令时实施的国家与地区

夏令时实施的国家与地区

蓝色为正在实施夏令时的过去和地区
灰色为曾经实施但现在已经取消夏令时的国家和地区
黑色为从未实施夏令时的过去和地区

     1916年4月30日,德国与奥匈帝国成为世界上第一组实施夏时制的国家,目的是为了能在战争期间节约煤炭消耗。在1970年代,由于美洲与欧洲地区也受到能源危机影响,至此夏令时开始广泛被实施。当下全球有共约70多个国家和时区在使用夏令时,我国也曾短暂使用过夏令时,但因节约能源效果不显著,以及对日常生活工作等带来的一些影响,到1992年全国宣布取消夏令时。

6.2、闰年与闰秒

     2008年是闰年存在2月29日,但微软一些软件在处理部分任务的时候会因为闰年导致处理错误。微软甚至在SQL Server 2008 CTP发布后曾经宣读了一份证明,建议用户不要在2月29日安装和运行软件,以减少影响。并且在Windows Small Business Server上还会出现更严重的错误:因为在微软的日历里根本没那么一天,因此就无法颁发证书。

  • 为什么要闰年

     闰年大家比较熟悉,闰年的设置是为了使日历年与太阳年(即地球绕太阳公转一周的时间)更精准地一致。严格来说地球绕太阳一圈的时间,大约是365.2422天。经过大约四年,累计误差将接近一天(0.2422 * 4 ≈ 0.9688天),但如果每4年就加1天,这样每128年又会多算出1天。所以基于此定义出了普通闰年与世纪闰年。

普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。
世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。

  • 为什么要闰秒

     闰秒[10]本质上和闰年的作用是一样的,也是解决时间解释运动中所存在的偏差。闰秒的调整是为了确保协调世界时(UTC)与地球自转时间(UT1)[11]保持一致。由于地球自转速度的不均匀性和减慢,UTC需要定期添加或删除一秒钟来进行调整,这一秒钟称为“闰秒”。

     国际地球自转与参考系统服务(IERS)是负责监测和发布闰秒调整的机构。ERS会根据地球自转的实际变化和测量数据,决定是否需要调整闰秒。闰秒通常在6月30日或12月31日的最后一秒添加或删除。这意味着在某些年份,时间序列可能会变为:23:59:59 → 23:59:60 → 00:00:00。

7、写在最后

     『存在不一定合理,但一定有原因』这是曾经我的主管跟我说的,至今我也受益其中。对所有事情怀有一丝怀疑心态,搞懂它的前世今生,或许它不那么合理,但至少当时这样做解决了一定的问题,我们在做新设计的时候可以提前考虑与规避。水多了加面,面多了加水,如果我们只是看到当下的混乱就指着“前人”没有设计思想没有技术匠心,却不了解最初“前人”这样做的意图与背景,骂着“前人”的我们终有一天也会成为后人眼中的“前人”。

     参考链接:
     [1]https://en.wikipedia.org/wiki/Unix_time
     [2]https://baike.baidu.com/item/世界时/692237
     [3]https://www.timeanddate.com/time/zones/
     [4]https://www.utctime.net/
     [5]https://baike.baidu.com/item/原子钟/765460
     [6]https://baike.baidu.com/item/闰秒
     [7]https://www.joda.org/joda-time/
     [8]https://jcp.org/en/jsr/detail
     [9]https://baike.baidu.com/item/夏令时/1809579
     [10]https://baike.baidu.com/item/闰秒/696742
     [11]https://zh.wikipedia.org/wiki/世界时

架构师之路

1、前言

     沈剑老师09年入职百度做即时通讯,13年开始才有意识的转型架构师,从即时通讯转到支付系统,克服了种种困难,完成了58同城即时通讯平台,支付系统重构等相关工作,之后不断地学习和进步,最终成为一名优秀的架构师。沈剑老师“身经百战”,很多业务系统设计工作都做过,在这条路上有着自己独特的体会和丰富的经验。下图展示了沈剑老师的任职与所负责的业务经历。

沈剑老师的架构师成长之路

     根据自己十多年的架构师经历,沈剑老师把自己的架构师之路抽象为三个阶段:

     打基础

     寻突破

     建体系

     以下是沈剑老师对这三个阶段所面临的问题与需要注意的重点地方的一些分享。

2、阶段一:打基础

     一般为从业的前3、4年,很难直接成为架构师,毕竟见识与经验尚浅,在语言层面、设计模式层面、业务逻辑层面等等,需要学习的东西还很多。这段阶段以学习技术、积累经验、增加自己的核心竞争力为第一要点,主要是了解工具、了解模式、了解各种玩法。沈剑老师认为语言对做架构设计的影响没有那么大,技术架构的路是相通的。在这个阶段,如果要找一个好的公司,沈剑老师认为需要考虑三个要点:

     是否重视产研:如果公司对于产品技术不重视,不利于这个打基础的阶段。比如百度就是非常重视技术,公司内部有各方面的专家,是非常适合应届生起步的一个公司。

     什么技术体系:公司是否有相对领先的技术栈或者技术理念也需要考虑,有一些公司会固守老旧的技术栈或技术体系,害怕技术革新,这对新人打基础是非常不利的。

     团队成熟度:团队成熟度也非常重要,太年轻的技术栈团队对于职业生涯前两年是不利的。

3、阶段二:寻突破

     第二个阶段是寻突破的阶段。打了三四年的基础之后,在某个方向上可能是半个专家了,这个时候要考虑以后的方向了,是向业务方向发展,还是向管理方向发展,又或者向架构师方向发展。沈剑老师认为不管往哪个方向走,都没有错,但是不能放弃技术,要时刻关注技术,因为无论哪个公司,综合型的人才都是最稀缺的。如果在这个阶段,要考虑换公司,沈剑老师认为需要考虑以下三点:

     快速发展,比成熟稳定好:这个阶段,快速发展的公司一般要比成熟稳定的公司更好,这时候机会更多,成长会更快。

     业务与技术的匹配度:如果想成为技术专家,比如往高并发、大数据方向走,公司的业务与技术的匹配度就非常重要,因为只有在实践中才可以获得最快地成长,有平台才能施展自己的抱负。

     深度or广度:如果要往业务的方向走,需要多关注业务的扩展度。如果要往综合管理的方向走,需要考虑在公司是否有机会带小组,是否能学到业务以外的东西。深度和广度没有绝对的正确,一般来说我们要成为“π”型人才。“π”的两条腿一条腿是技术支撑,一定要在某一方面有深度,成为某一方面的专家;另一条腿是沟通和交流的能力,要有能力去带团队。这个阶段,自己去主导一些项目,做出一些成果,突破自己,证明自己是首先应该考虑的。

3、阶段三:建体系

     工作了8-10以后,不管是往哪个方向走,都要开始建立自己的体系了。在这个阶段,更多地要考虑就不仅仅是工作了,更多的是考虑自己的事业。这个时候注重以下三点:

     平台很重要;

     空间很重要;

     系统性思考,战略性思维。

     作为事业,平台能不能让你自己施展抱负,完成自己的事业、空间够不够大就很重要。这时候要系统性思考,要有战略性思维,要考虑自己未来的路,如何去完成自己的事业。

     总结来说,沈剑老师用一个“干”字总结自己的过去十几年。展开来说,首先就是需要持续学习,不断地去做新的业务,多去交流,多向其他人学习,打好基础,积累自己的核心竞争力。这个过程可能会压力很大,但是收获也会很丰富。其次,做各种业务系统,重要的是要积极主动的去承担工作,不要太在意工资,只要有相对公平的环境就可以,这时候要拼命地干,尽力而为是不够的,要全力而为。

一帮弱智,促成了互联网上最不可名状的低级狂欢

     在互联网时代,尤其是进入移动互联网以来的短视频时代,知识通过互联网走向“市场”,人们不再创造知识,而在“贩卖”知识;互联网也促使各种有害的知识或“伪知识”登上“舞台”甚至进入主流,因为人们衡量知识价值的标准成了金钱和流量。这最大后果是让一群低学历、低素质、无底线的人成为舆论的主流,让谣言、仇恨、戾气替代真相、正义、文明。

一帮弱智,促成了互联网上最不可名状的低级狂欢

不是读书无用,而是你无用

     每隔一段时间,“读书无用”的论调就会出现在人们的生活中。鼓吹者们言之凿凿地举出不少例子:隔壁村的张二,小学都没毕业,生意做得有模有样;刻苦用功十八年的老同学,还是个拿死工资、从牙缝里还房贷的小职员。底气之足,让我瞠目结舌。

     在众声喧哗的读书无用论中,我比较注意三种声音。

     一种读书无用论的鼓吹者,自己真没读过几天书,但或是其他能力突出,或是运气较好,也取得了不错的成就。你的旧友聚会,或许也有这样一种悲凉的酸楚:极没文化的发小,居然成了大款。我们这些读了十七八年书的,除了学位啥也没有。他们给你倒上茅台酒、递来中华烟,再送你一句加了冰块的风凉话:文化能当饭吃啊?不错,沟通能力、交际能力、执行能力,确实很重要,“成功者”不一定都是读书人,但读不读书,在很大程度上决定了一一个人究竟能够走多远。

     另一种读书无用论者,确实读过几年书,甚至还有相当漂亮、镶着金边儿的学历背景。你跟他聊哲学,他能把纯粹理性批判给你讲得头头是道;你跟他谈美学,他能把斯宾诺莎、海德格尔诸人的美学观梳理得脉络清晰。回翻他的在校表现,还真是可圈可点。但眼下,知识和财富之间的转化很不尽如人意,甚至在清贫愤懑、怀才不遇中挣扎。在功利意图的驱使下,读书不是为性情的雕琢、底蕴的贮藏、襟怀的开阔,完全是为换得利益,一旦变现受阻,就觉读书无用。

     这些人怯于面对的事实是: 不是读书无用,而是你自己无用。 你确实是不错的考试选手,确实从字里行间咂摸出了些墨水味,但失去了书本的荫蔽,你再没有半分优势。你的视角局限在那几本偏狭的书本里,却不知大千世界的无限可能。你只能在故纸堆里与前人对话,却不具备在现实世界里周旋的本事。种种无用中,最无用的是将自己的一事无成归结为读书所致——我失败不赖我,赖读书没用,要不是当初浪费那么多时间去读书,也许就有用了。读书无用论,给他们提供了那么舒适、有面子、有理由的庇护所,那么理直气壮地回避了自己的无能。

     种种读书无用的论调中,最可恶的一种是别有用心者。明知开卷有益,却巴不得周围所有人都沉浸在玩乐中虚掷青春。每个人的学生时代,都会有这么几个同学:熬夜的黑眼圈挂在脸上,偏偏大言不惭地告诉别人自己从来不学习。明知课堂所学东西的价值,非要激进地说这种填鸭式的教学毫无意义。他们几乎是人格分裂的——一边拼命地读书,一边一脸厌弃地说读书无用。

     在他们看来,如果读书无用论能大肆风行,那么每多一个信奉者,自己就少一个对手。如果班上的同学都不读书,那么寥寥几个的保研名额非他莫属。如果同年进单位的新人都不读书,那么获提拔擢升机会的更有可能是自己。目光灼灼盯着一己之位,置社会风气于不顾,是为自私。比自私更浓烈的,是自卑的心理底色。这种人看似很有“谋略”,其实最没用,他不敢光明正大地迎接任何一种透明公开的挑战与竞争,只能动用这样卑劣的手腕,遮掩迫切求胜的病态竞争心理。

     在这个涌动着反智情绪的社会中,读书无用论总轻易地受到众多赞扬、读书人的悲凉处境总是被带着嘲讽的态度围观,读书人的负面信息总是被满含鄙夷地放大。说实话,我也被无数次问过,你读北大出来能干什么?不还得跟我一样工作挣钱吗?读那么多书不还得嫁为人妇吗,有什么用?对此,我想说的是:哪怕我们做着同一份工作,我不会同你一样目光灼灼地盯着眼前得失;哪怕我们都将在家庭的琐碎中度过,我知道琐碎之中也有诗意与温情;哪怕我们都将面对生活的苟且,我会为我的子女在嘈杂中开辟一道安静的缝隙。

     而如果我一无所成,我绝不拿读书无用来遮掩我的无用。因为我读过书,油墨已融入骨肉里,而你没有。

底层巨婴父母,一辈子无药可救

     现在很多50,60多岁的父母,其实本质上是个巨婴,他们并不比孩子成熟到哪里去。

     《情深深雨濛濛》里,黑豹子陆振华就是典型的巨婴父亲,依萍因为家里揭不开锅跑去要生活费,因为几句话,结果换来了一顿毒打,最后依萍走投无路,去了歌舞厅上班。

     所谓的巨婴父母,他们只允许别人顺着他们,只喜欢听好话,否则就会脾气暴躁。巨婴父母没有处理冲突的能力,要么语言攻击,要么使用暴力,所以孩子在他们的教育下也很容易走极端,一根筋(庆幸自己没有成为这样的人,反思自己的整个过程,我认为读书和思考很重要,读书和思考几乎是普通人逆天改命唯一的途径了吧)。

     巨婴父母有三种典型特征,如果你不想自己成为巨婴父母,就一定要在生活中注意克制。

1、同理心很弱,觉得自己总是对的

     一般来说,读书太少的人,没有反思习惯的人,同理心都非常弱。上一代50后,60后因为所处时代问题,受教育程度很低,加上是在农村,社会分工不足,普遍同理心比较弱。

     同理心弱的表现是:他们无法理解别人,也无法真正认识自己。比如别人好心指出他的错误,他不会思考对方是不是对的,而是会开始恼羞成怒,甚至是开始破口大骂。

     古代有句话很经典:”唯女子和小人难养也。”因为在古代,女性基本不怎么读书,加上女性比较感性,所以跟他么讲道理基本等于对牛弹琴。而进入21世纪,读书普及后,这个现象好了很多。

     同理心弱的人,一般社会地位都比较低,因为他们不会处理人际关系。而那些敢于认错,敢于自嘲的,往往很受欢迎,所以最后他们混的都普遍不错。

2、对任何人都不尊重,包括孩子

     巨婴父母一般不会尊重任何人,但是他们很懂得欺软怕硬。

     在孩子很小的时候,巨婴父母经常口头谩骂,甚至暴揍孩子。他们是“棍棒底下出孝子”的忠实信徒,本质上他们根本不懂如何教育孩子,而使用暴力来欺负弱小的孩子,倒是从小耳濡目染。

     其实巨婴父母也挺可怜,他们的父母也是巨婴。所以巨婴父母培育巨婴父母,但是他们绝对不会认为自己是巨婴,而是认为自己是一个合格的普通父母。

     所以开头说,陆振华是巨婴父母,就是这个道理,他们本质上除了自己,谁也不放眼里。他们骨子里缺乏对生命的尊重,对孩子的尊重。他们很多人都把孩子当做是私有财产,想怎么处置怎么来。

     所以在这种高压环境下,巨婴父母的孩子长大后一般很缺爱,对人又比较冷漠,和那些正常有爱家庭的孩子,一眼就可以区别开来。

3、自卑懦弱,敏感而情绪化,缺乏自我控制力

     一般来讲,6岁以下的小孩缺乏情绪控制能力,但是如果父母会正面教育他们,给他们提供一个好的榜样,孩子也会慢慢成熟。12岁左右的小孩,情绪管理能力其实和成年人不会差距太大。

     而在巨婴父母的教育下,因为父母缺乏情绪管理能力,经常把负面情绪带给孩子,所以孩子的情绪也会经常波动。

     很多巨婴父母自卑懦弱又敏感,一旦被家人指责,就容易发脾气。然后他们还会把自己的情绪差怪罪给家人,其实家里所有人都是巨婴父母的受害者。

     很多人说娶老婆一定要娶一个原生家庭幸福的,情绪稳定的,因为娶一个情绪稳定的,这个家庭里的三代人也许不会大富大贵,但是起码拥有岁月静好。

     如果娶一个原生家庭父母天天吵架的,那么她的脾气大概率好不到哪里去。然后呢?你这个家庭里的三代人都会被她搞得鸡犬不灵。

4、最后的话

     这个世界最大的漏洞在于,生养孩子不需要任何资格和学习,所以才有那么多巨婴父母的产生。

     如果你的父母是巨婴,那么很遗憾,你这辈子想要改变命运,一定要远离巨婴父母,一定要多读书,多和成熟稳重的人来往,否则大概率是重复你的父母之路。

     如果父母是巨婴,那么尽量不要太早结婚,否则最惨的是无辜的孩子。

对于新岗位的苦恼

       最近岗位上发生了调整。原平台开发的主职不变,在项目上的兼职从手机银行调整为小程序平台的技术经理,主要任务是基于开发平台对小程序做技术架构改造。但是一周了解下来,外包公司开发人员的专业素质和职业素养令我感到担忧,我没有把握在这些人的配合下,能将这件事情做好。举例如下:

  • 网关作为一个全局性的流量收口,主要承担协议转换、限流熔断等服务治理、鉴权等功能。但是网关服务中,被堆积了大量的业务逻辑:

网管服务中的大量业务代码

  • 缺少准入校验导致的大量的数据权限越权访问:

准入校验

  • 编码风格惨不忍睹:

编码风格

  • 逻辑不清:

逻辑不清

一个非常好用的settings文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<profiles>
<profile>
<id>pentaho</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<file.encoding>UTF-8</file.encoding>
</properties>
<repositories>
<repository>
<id>pentaho-public</id>
<name>Pentaho Public</name>
<url>https://repo.orl.eng.hitachivantara.com/artifactory/pnt-mvn/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>pentaho-public</id>
<name>Pentaho Public</name>
<url>https://repo.orl.eng.hitachivantara.com/artifactory/pnt-mvn/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>aliyun</id>
<properties>
<file.encoding>UTF-8</file.encoding>
</properties>
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>activiti-repos2</id>
<properties>
<file.encoding>UTF-8</file.encoding>
</properties>
<repositories>
<repository>
<id>activiti-repos2</id>
<name>Activiti Repository 2</name>
<url>https://app.camunda.com/nexus/content/groups/public</url>
</repository>
</repositories>
</profile>
<profile>
<id>mvnrepository</id>
<properties>
<file.encoding>UTF-8</file.encoding>
</properties>
<repositories>
<repository>
<id>mvnrepository</id>
<name>mvnrepository</name>
<url>http://www.mvnrepository.com</url>
</repository>
</repositories>
</profile>
<!-- Spring Snapshot Profile -->
<profile>
<id>spring-snapshot</id>
<properties>
<file.encoding>UTF-8</file.encoding>
</properties>
<repositories>
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>

<pluginGroups>
<pluginGroup>org.pentaho.maven.plugins</pluginGroup>
<pluginGroup>com.pentaho.maven.plugins</pluginGroup>
<pluginGroup>com.github.spotbugs</pluginGroup>
</pluginGroups>

<activeProfiles>
<activeProfile>aliyun</activeProfile>
<activeProfile>pentaho</activeProfile>
<activeProfile>activiti-repos2</activeProfile>
<activeProfile>mvnrepository</activeProfile>
<activeProfile>spring-snapshot</activeProfile>
</activeProfiles>
</settings>

星际穿越混剪

  • Copyrights © 2017 - 2025 杨海波
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信