建议没有恋爱经验得男生做到通篇背诵!

女人相亲惯用套路

第一招:打压你的婚恋价值

从长相、条件、性格等角度打压你,让你认为自己存在明显缺陷。 比如你有房有车,那就说对你没感觉;比如你家境不错,那就说你工作不行;比如说你什么都不错,那就说你身高不行;没有人是十全十美的,一旦开始打压,总能找到缺陷。 一般使用这招的女性,自身条件都十分拉胯,寄希望于嫁给更好的男人,但又害怕男人醒悟,所以想用打压价值的方法强行匹配。 辨别的方法很简单,真正善良的人不会主动去打压他人。 但换句话说,女人在相亲时选择打压你,大概率是她不太行,你很行(分人,自己判断)。

第二招:享受你的婚恋价值

通过最初的阶段后,女性往往会以试试的借口,享受你婚恋价值带来的好处,比如日常接送、买单、送零食奶茶等,美其名曰,培养感情,实际上就是还没想好要不要跟你谈,但想先拿点好处、或者享受一下优越感。 我个人认为,任何不给你名分的相亲对象,都必须直接 PASS ,没有什么所谓“试一试”、“试用期男友”的说法,就像你不可能跑去超市买一瓶水,喝一口又放回去。 我曾经给一个女人当过一年半的试用期男友,我想没人比我更懂试用期男友的痛苦。

第三招:强制要求你接受她婚恋价值中的缺陷

比如家里穷啊、有无能弟弟啊、父母有性格缺陷啊、工作不好啊、个子矮啊、打过胎啊、惯性流产啊之类的。 一开始接触的时候她不会坦白,等感情升温后,她才选择告诉你真相,这时候如果你不能接受,那你就是渣男、就是背叛感情;如果你能接受,那以后你都必须一直接受,你反抗就是你渣男。 实际上,很多女性都喜欢使用这一招,将本来该由自己承受的道德压力,转嫁给不知情的男性来承担,这样女性就会立于不败之地。 不得不说,女性在这方面简直是天才级别的演员。

第四招:事后补救

有别于上述三招,因为使用这一招的女性,大概率是初次相亲或者对自身抱有不切实际幻想的女性,她们难以判断自身的婚恋价值,不知道自己足以匹配什么样的男性,对自己未来的婚恋对象产生了过高而不切实际的期望,所以大概率都是发现问题后秒拒相亲对象。 一旦遭遇多次相亲毒打后,她就会发现自己以往碰到的某位男士,就是她能匹配到的最好的男人,然后开始进行撩拨。 一般是发条微信、或者带照片的朋友圈,寄希望于你能主动上钩去撩。 一旦男性在这时候上钩,女性反而会产生“也许我还值得更好的”的念头。 这种女性十分可怕,因为你永远不知道她欲望的尽头在哪里。即便进入婚姻状态,她的欲望也不会消退。我愿称之为骑驴找马的神。

遇上前三招中任何一招,都白雪公主,因为前三招往往是伴生的组合拳。而第四招往往出现在本身条件 OK 的女性身上,如果你对自己有信心,可以考虑接触,但我个人是不建议的。

最后提醒一句,任何善良、真心想要和你继续相亲的女孩子,都不可能对你使用以上任何一招,用了就是有问题,就是不善良。 去相亲的老哥千万不要自我怀疑,因为一旦自我怀疑,就会迪化,然后陷入连环 PUA 陷阱。

切记!

—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​—​

第五招:敲山震虎

确立关系后也并不安全,女朋友时常会暗示一些奇怪的东西,比如“我有一个朋友,她男朋友 blablabla”。 切记,一旦出现“我有一个朋友”这个句式,一般就是在表达自己深层的择偶观念,女性一旦混成圈子,就会觉得圈子内的彼此都是条件相似的, 而她此时提出“别人家的男朋友 blablabla”,就是暗示你“别人有的,我也要有,我没有,不是我的问题,因为我和我朋友差不多条件,所以是你的问题”。 该怎么做不用我多说了吧?

第六招:时间尺度错乱之付出收获匹配法

很难描述的招数,打个比方,假如你现在对她如何如何如何,她就会把时间拉到“几十年”、“一辈子”这样无法立时衡量的时间尺度上,对你的付出进行打压。 一般遇上这一招的男性,都会立刻承诺或是陷入懵逼状态,然后女性就可以趁机把你之前的付出打压下去,然后运用“历史平均”这个手法,将你付出的价值分散,以此掩盖自身没有付出的短板,从而达到所谓婚恋关系中的“付出—收获”公平匹配。

第七招:自我拔高

这一招的适用对象,往往是家庭条件极为优秀的大中产家庭出身的孩子,但又存在一定缺陷(比如长相不算帅的路人、性格较为沉闷、为人老实等)。 女性在面对这种婚恋价值极高的男性时,反而会表现出“超规格”的矜持,因为她们认为这种矜持可以拔高自身的婚恋价值。 对待这一类男性,女性往往喜欢不断用各种“婚恋关系中的无价值条件”,对自身进行自我拔高。 打个比方,她会不经意提起自己去过很多地方,见过很多世面,有一些很厉害的朋友,以此来彰显自身的一些价值,但她就是不提“自己在工作上有什么进步”、“自己在理财上有什么收益”、“自己在家庭教育上有什么观点”,众所周知,前者在男方眼里都是“无价值婚恋条件”,后者才是“有价值的婚恋条件”,一旦女性主动提出前者而忽略后者,就是在试图强制性把一些“无价值”的条件打造为“有价值”的条件。 男性一旦被忽悠,认同了这些“无价值婚恋条件”,就会在心底拔高女性的婚恋价值,然后达成一种非常强行的“匹配”。

所以,男性必须要深刻明白,什么是有价值的婚恋条件,什么是无价值的婚恋条件。 打个比方: 有价值的婚恋条件:女方的家世清白、女方的父母没有犯罪记录不会导致孩子政审失败、女方有一份稳定而达到平均收入水平的工作、女方对未来有自我规划(不是白日做梦,是真正的自我规范)、女方的容貌身材、女方持有较为稳定的人格与性格等

无价值的婚恋条件:女方有一门不能带来任何收益、也不能陶冶情操的兴趣爱好、女方有很多自认为很厉害的朋友、女方看过世界、女方因工作原因见识过更好的生活等。

第八招:负面情绪转移与正面情绪控制

很多男性遇到过,女朋友或预期会成为女朋友的女性,突然因为与你不相关的事情,产生了负面情绪,并要求你共同承担。 这种手法往往是将自身的不幸强行发泄在男性身上,以此达到情绪的宣泄与平衡,还美其名曰“共同成长”。

而正面情绪控制就更简单了,你有什么想分享的快乐,她不但不接收,反而立刻对你的快乐进行控制。 打个比方,你听到一首很好听的歌,她就说听歌没用,不如上进一些;你学会了某项兴趣爱好,来宣泄自身的情绪,她还是会说这些东西没用,不如赚钱;你要是多赚钱,她就说钱不是唯一的快乐。 总之,你想快乐,她就不让你快乐,你的快乐必须建立在她允许的范围内,她让你快乐,你才能快乐,她不快乐,你也不能快乐。

其实这是精神控制的一种,字母圈常用来调教 M 。终极目标就是让你变成一个“完全与她情绪同步的工具人”,一方面可以让你失去对自身情绪的掌控能力,逐步沦为玩偶,另一方面也可以将你变成一个纯粹的“情绪垃圾桶”,以此宣泄自身无能带来的负面情绪。

第九招:薛定谔的受害者

打个比方,在一段婚恋关系中,女性一旦出轨,就会将锅甩给男性,提出“是你一直不在我身边”、“是你 X 能力不强无法满足我”、“是你不能平衡工作与生活”。 可实际上大家都明白,出轨才是过错方,女性这样做无非是想减轻自身面对的心理层面上的道德压力与社会层面上的舆论压力,将自身转变为受害者,使自身处于“受害者与加害者的叠加状态”,以此迷惑男性直观感受。 实现心理层面与社会层面的翻盘。 这一招不一定是用在出轨上,但一经使用,大概率不是已经出轨,就是在出轨的边界线上左右横跳了。

以第九招为基础衍生出的第十招:舆论伏笔

女性是天生的舆论控制者,而且极其擅长埋伏笔。 打个比方,她会提前向你们共同的朋友倾诉感情,以个人角度描述你们之间的关系,让你们共同的朋友觉得你不对劲, 以此为基础,当她终于犯错时,她就会使用第九招,这样,被她埋下的舆论伏笔所长期影响的那些朋友们,天然就会对她产生同情,反过来指责并没有产生“实际加害行为”的男性。 以此,女性得到了舆论上的胜利,而一些较为软弱善良的男性,反而可能陷入自我怀疑、长时间无法从中走出。

第十一招:预设立场

相信很多朋友在婚恋关系中都遇到过这个问题,比如,女性看到一则婚恋有关的人类迷惑行为大赏,就会预设立场,将自己预设为受害者,将男性预设为加害者,然后要求男性从加害者的角度出发,阐述自身观点。 男性在此时往往陷入圈套,然后陷入争吵。 打个比方,一桩离婚案,男性出轨,女性受难,然后女朋友借机发挥,预设你就是出轨方,然后要求你从出轨方角度进行阐述,分析自身的一些行为,做出一定的保证。 再打个比方,同样是上述案例,女性直接带入被害者视角,将你想象成加害者,直接了当将自己和你的立场进行预设,然后对你进行粗暴的价值观输出。 即便你根本没犯这个错,但价值观是一定要输出给你的,而且一定会将你预设为加害者那一方。

准确些说,这也是情绪控制的一种延伸——价值观控制。 但手法更为高明,因为一旦将自己预设为被害者,将男性预设为加害者,就可以立于不败之地,因为吵到最后,有一个已经出现受害者的案例就摆在你们眼前,一旦男性从加害者角度出发进行阐述,是怎么也不可能吵赢的。 女性从而输出自身的价值观,对男性的价值观进行打压,达到控制的目的。

第十二招:饱和式恋爱

女性最喜欢纠结一个问题:异性间是否存在纯粹的友谊。 以此为基础对男性进行迷惑,实则女性十分清楚自己身边男性们的想法,并对此加以利用。 举个例子: 一位女性即便拥有了男朋友或是老公,她也会不自觉开发其他男性,以作备用,这是一种饱和式的恋爱方法,一旦男友或老公出现问题,女性立刻就可以踢掉换人。 或者换一种说法,女性十分擅长给男性添加“定位”,男朋友是“男朋友”,另一位男性是“可以进行情绪宣泄的二号垃圾桶”,再一位男性是“可以帮忙完成工作或课业的工具人”,以此类推。 即便步入婚恋关系,这种饱和式恋爱手段也不会停止。

第十三招:历史投影

女性擅长从时间长河中召唤前男友的历史投影,这些历史投影往往不具备独立人格,是完全利于女性、完全辅助女性观点的人偶。 这些人偶的存在就是为了单方面证明女性想要阐述的观点、想要输出的价值观、想要达成的目的。 当前男友的历史投影降临时,老哥们往往被打得束手无策,因为你不可能击杀历史投影,那只是虚无的一个片面人格,更别说女性可以召唤大量历史投影对你进行围攻,你是万万不可能战胜一切的。

这里需要注意的是: 1.历史投影的选取目标,不局限于前男友,有时候优秀的前追求者也在被选召的范围内。 打个比方:一名女性年轻时被高富帅追求过,那么在年轻时,她就觉得自己的婚恋价值足以匹配这位高富帅;等到年纪大了,被毒打过后,她虽然心里明白自己不匹配,但嘴上不会承认,不仅不会承认,反而会利用这些优秀的前追求者,对老哥们进行降维打击,以此达到自身的目的。

2.历史投影很可能并不存在,是女性依靠身边朋友的经历、网上的段子,进行编造的、彻底的虚无造物。

所以说,一旦女性从时间长河中召唤历史投影,老哥们是万万打不过的。

第十四招,也是我最厌恶的招数:旁敲侧击、步步为营

打个比方: 1 、女性开始若有若无地跟你讨论某些问题,频率极大时,就是在试探你的价值观,试探你对这些问题的态度,而往往,问这些的女性本身就存在这些问题(比如流产、是不是**、婚前同居、出轨等)

2.女性开始不断用各种小的方面突破男性的底限,举例子:你恐高,那就非要你陪着坐过山车;你怕水,就非要你一起去游泳;你比较害羞,就要你疯狂地在大众面前展现爱意;你比较古板,就要你学会少年气。 总之,你原先的原则都要被逐步瓦解,最终的试探是:如果我出轨,你还能接受我吗?如果我毁容,你还会接受我吗?如果我重病,你还会接受我吗? 通过不断突破男性的底限,达到控制与预埋伏笔,为自己日后犯错寻找适当的借口。

以上两种方式,往往不会集中体现,一旦男性表现出反抗,女性就会顾左而言他,冷却一段时间,然后利用别的方法再次试探。 女性在婚恋关系中这种不正常的试探底限的心理,以及以婚恋关系为要挟手段,所进行的强制突破底限行为,在字母圈里一般称为“调教”。

在字母圈里,一旦你被“调教”,你的 XP 就再也刹不住车;同样的道理,在现实生活中,一旦你被“试探、突破”,你生为正常男性的底线也将不复存在,得到的只会是女性不断的、肆意妄为的、更多的“试探与突破”。

第十五招:医生

有不少女性经历过婚恋关系后,逐渐将自己视作“病人”,将后来的男性视作“医生”,她们将上一段失败的感情所留下的创伤视作“病症”,她们要求“医生”必须能治疗“病人”,一旦无法痊愈,就会将所有罪责怪在“医生”身上。 打个比方,一位女性曾遭遇过海王,有很强的不安全感,所以当她遇见新男友时,就会强制把上一段关系中受到的伤害转移到新男友身上,她对上一段关系的总结和应对手段,全部都会施加在这位新男友身上。 包括但不限于“对安全感的不断强调”、“对新男友的人身控制、社交控制,乃至于精神控制”,虽然新男友并不是造成她这些“病症”的加害者,但作为新“医生”,新男友必须负责治疗,且要治疗好,否则就是新男友的问题。

可众所周知,再好的医生也不能治百病,心病还需自愈,莫要折磨他人。

第十六招:人设

女性对人设的痴迷可以说达到了可怕的地步。 对于新认识的异性,女性擅长通过碎片化的信息,对这些异性进行“人设预构建”,也就是我们常说的“贴标签”,你表现得很有钱,给你贴上“富人”标签,你表现得很温柔,给你贴“暖男”标签,以此类推。 当女性为男性贴上这些由碎片化信息营造出的“人设”后,她们的大脑会不自觉遗忘本来的男性,而开始对这些反复加深记忆的“人设”,进行二次加工。 很多男性可能很疑惑,为什么我明明不是那样的人,但女性就认为我是那样的人,其实很简单,因为你被预先构建了一个“人设”,你的所有行为,都是这些“人设”的二次加工和深化改造,你跳不出这些预设定的“人设”,自然会成为被误解的那个人。

这一招说实话,不算坏,但主要是阻碍男性与女性进一步交流,因为男性一旦被预设人设,后续的动作都会被归入这个初始人设中,一旦超出这个人设的设定,就会带来毁灭性打击,也就是男性经常遭遇的,女性突发暴躁情况,实际上就是你在她心中的人设被破坏掉了。

现实中很多男性不会创立自己的人设,所以才被牵着鼻子走,一旦有心利用女性这种心理,可以大大缩短与女性接触的麻烦,快速在她心底强化自身形象,而后达成一些不可告人的目的。 实际上,很多 PUA 案例中的被害者女性,就是被“人设”欺骗,然后自动开始为这些诈骗者的“人设”添砖加瓦,以至于落入 PUA 陷阱。

我个人不太提倡善良的老哥去营造自己的人设,因为这很不善良,同时也提醒女性朋友,人设终究是假象,不要试图用碎片化信息结构一个活生生的人,这样得到的只会是你预先想要的答案。

第十七招:围点打援

女性经常会揪住男友或老公的某一个缺点不断攻击,但如果你认为,女性只是对这一点有抱怨,那你就大错特错了。 女性实际上是不好对你直接进行全面批判,所以才从你的诸多“缺点”中选取某一个,然后重兵围困,这种时候,老哥们常用的方法就是派出“援军”。 这里所说的“援军”,就是老哥们自认为的自身优点,老哥们以为“援军”到了,围城可以被破掉,可实际上女性就是等你的“援军”过来,然后对“援军”进行伏击,从而达成以点破面,以局部优势打整体优势,分而治之的目的。

打个比方: 老哥洗澡不频繁,然后女性指责你,你会说“我工作很努力,只是太累了才不洗澡”、“我很用心对你,但我确实洗澡不频繁”之类的话,然后女性就会放弃“不洗澡”这个点,一一击破你派出的“援军”。 到最后,你发现自己被骂了个通透,好像一无是处,而女人也发泄了心中长期的不满,将自己的隐性要求展露,并再一次巩固了自己的优势地位。

引申一下:这一招一旦使用,后患无穷,因为她的指责全部都是她潜藏的目的,是对老哥未来人生规划的硬性要求,一旦达不到,她就可以借题发挥,然后引申回最初那一幕,表示是老哥的问题,是老哥没有理解她的意思,她明明已经表达过了,是老哥没有用心。

第十八招:标准指定+定价权+市场垄断

1.标准制定,这很好理解,也就是婚恋关系中,所有的规则都由女性来制定、修改、补充,男性只能在女性制定的规则内玩。

2.定价权,婚恋关系中,双方的投入所换算的价值,完全由女方来决定其高低。

打个比方,男方日常接送、投喂、倾听甚至负担更多账单,男方认为自己付出更多。 可一旦和女方发生争辩,从女方口中再次听到这些行为的价值,男方就傻了。 因为女方可以随口改变你自认为的高价值婚恋行为,并进行压价,而你没有定价权,你只能傻听着,说不定还会在潜移默化下,认可女性对你所投入的价值的定价。 同时,女方即便付出更少,但通过定价权,也可以直接提高自身婚恋行为的价值,以此维持一种"虚假"的公平。

3.市场垄断,进入婚恋关系后,女性往往会要求男性断绝异性联系,而她自己会找各种借口,保存自身的异性人脉。 这就是垄断,将男性的选择权彻底夺走,却保留自身的选择权,配合第十二招的饱和式恋爱,长久下来,男性会逐渐失去正向的婚恋价值(没错,和异性多接触,就能提高自身的婚恋价值),而女性得以保存这种价值。 当感情真的走到陌路的时候,哪一边吃亏,不言自明。

相信上过班的老哥,比较理解这种手段的可怕性。

第十九招:啄木鸟

招如其名,啄木鸟不断啄击大树,看起来没多大影响,实则会在大树身上留下数不清的小孔,还美其名曰“捉虫”。

这种战术在实战中一般表现为:突发性在你身边叹口气,你去问又说没有;突然表现得极为沉默,不接你的话,让你很尴尬;突发性表现出萎靡不振的样子,让你担心又不说清楚原因。 不是一次,不是几次,是分成上百上千次,隐藏在你生活的每一个片段里。 可能有老哥要问了,这有什么用吗? 当然有用。 这个战术一旦潜移默化开始影响老哥,就会达到浅层次的情绪控制(到最后,她只要啄一下,你的情绪就会开始波动、害怕、担忧,怀疑自己身上出现了“虫子”),实现低层次情绪暴力的效用(你的情绪因她的情绪而波动,每日都担心她会啄一下,严重的情况下,一天可以被啄很多下)。

这招最可怕的是,不易判别,不易发现,即便发现了,也没有太好的应对方式,大多数时候,男性因为本身被要求坚强,是难以对啄木鸟说不的。 可就我观察来看,男性的心理其实相当脆弱,在啄木鸟的不断啄击下,男性内心遗留的破防效果是连续且久远的,处于啄木鸟长期不间断打击下的老哥,最严重的情况下,会出现完全丧失自信心、完全丧失生活乐趣的情况(详细参考 40 岁左右的中年男性的心理状态)。

这一条,女性也经常用来对付孩子,所以老哥们家里如果有孩子,老婆又不经意使用啄木鸟战术,老哥们最好能和自己老婆谈谈,这种战术会像慢性毒药一样,缓慢摧毁掉孩子的信心。

其实在人际交往中,啄木鸟也很可怕。比如一个不算亲近的朋友,每天找你借点什么,可能是从卷纸上撕一点点纸,可能是拿走你一根笔,也有可能是找你带顿早饭不给钱,日积月累的占便宜行为,实际上就是一种啄击,让你这颗大树很不爽,但又不能反抗。久而久之,朋友占了便宜,你反而心情越来越差,内心中还产生了“不就是那么点东西吗,我到底在生什么气”的道德枷锁,最严重的情况下,你一看见那位朋友,就浑身不舒坦。 这种人际交往中的啄木鸟,多发于住校学生中,为人父母的老哥可以常常和孩子们交流、交流,免得孩子一直沉浸在“因小事产生的道德疑惑,继而产生的看似对他人厌弃,实则是自我厌弃”的情绪中。


转载自 https://www.v2ex.com/t/944629

linux 下利用 openssl 生成 12 位随机密码,只包含 0-9a-zA-Z 这些字符

openssl rand -base64 12 |tr -dc '0-9a-zA-Z' |head -c 12

友情提醒:如果需要特殊字符,建议随便在任意位置插入一个或若干个,比如 _-.?>< 等等字符

当然了,也可以使用 /dev/urandom,下面是个例子

$ LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()' </dev/urandom | head -c 12
fHb!uaM8YFYw

来自你的消息:

在 linux 下使用 openssl 生成随机密码,请写出几个例子

来自 ChatGPT 的消息:

当在 Linux 下使用 OpenSSL 生成随机密码时,可以使用以下命令和选项:

  1. 生成一个包含字母、数字和特殊字符的随机密码:

    openssl rand -base64 12

    这将生成一个长度为 12 的随机密码,包含大小写字母、数字和特殊字符。

  2. 生成一个只包含数字的随机密码:

    openssl rand -base64 8 | tr -dc '0-9'

    这将生成一个长度为 8 的随机密码,只包含数字。

  3. 生成一个只包含字母的随机密码:

    openssl rand -base64 10 | tr -dc 'a-zA-Z'

    这将生成一个长度为 10 的随机密码,只包含字母(大小写)。

  4. 生成一个指定长度的随机密码,并将结果保存到文件中:

    openssl rand -base64 16 -out password.txt

    这将生成一个长度为 16 的随机密码,并将结果保存到名为 "password.txt" 的文件中。

请根据需要选择适合的命令和选项,生成符合您要求的随机密码。

来自你的消息:

我执行了 openssl rand -base64 12 生成的结果是 1lWwKRocbOmXl3Zt 这个不是 16 位么,怎么是 12 位

来自 ChatGPT 的消息:

非常抱歉,我之前的回答有误。openssl rand -base64 12 命令生成的结果确实是 12 个字符,而不是 16 个字符。我混淆了字符数和字节数。

在使用 openssl rand -base64 命令时,每个字符由 6 位二进制表示。由于 Base64 编码使用 4 个字符来表示 3 个字节,所以 12 个字符实际上是 9 个字节。

如果您需要生成 16 个字符的随机密码,您可以执行 openssl rand -base64 16 | head -c 16 命令。这将生成 16 个字符的随机密码,并将结果截断为所需的长度。

非常抱歉给您带来了困惑,希望这次的回答能够解决您的问题。

来自你的消息:

openssl rand -base64 生成的字符串可能会包含 = 符号,我只想要数字和大小写字母,应该如何控制?

来自 ChatGPT 的消息:

如果您只想要生成包含数字和大小写字母的随机密码,并且不包含特殊字符或等号(=),您可以使用以下命令:

openssl rand -hex 12 | tr -dc 'a-zA-Z0-9' | head -c 12

这个命令会生成 12 个字符的随机密码,只包含数字和大小写字母,并且不包含特殊字符。openssl rand -hex 12 生成的是 12 个字节的随机数据,然后通过 tr -dc 'a-zA-Z0-9' 过滤掉除了数字和大小写字母之外的字符,最后使用 head -c 12 截取前 12 个字符作为最终的随机密码。

请注意,由于只包含数字和大小写字母,这种密码的强度可能较弱。如果您需要更强的密码,可以增加密码的长度或者包含其他字符。

来自你的消息:

openssl rand 有哪些用法?

来自 ChatGPT 的消息:

openssl rand 是一个 OpenSSL 工具,用于生成随机数据。它可以用于多种用途,例如生成随机密码、密钥或初始化向量等。以下是一些常见的 openssl rand 命令用法:

  1. 生成指定长度的随机字节:

    openssl rand -out random.bin 32

    这将生成一个包含 32 个随机字节的文件 random.bin

  2. 生成指定长度的随机十六进制数:

    openssl rand -hex 16

    这将生成一个包含 16 个随机十六进制字符的字符串。

  3. 生成指定长度的随机 Base64 编码字符串:

    openssl rand -base64 24

    这将生成一个包含 24 个随机 Base64 字符的字符串。

这些只是 openssl rand 命令的一些常见用法示例。你可以通过运行 openssl rand --help 查看完整的命令选项和用法说明。

来自你的消息:

openssl rand -hex 12 | tr -dc 'a-zA-Z0-9' | head -c 12 这个命令里, tr -dc 是什么功能,解释一下

来自 ChatGPT 的消息:

在给定的命令 openssl rand -hex 12 | tr -dc 'a-zA-Z0-9' | head -c 12 中,tr -dc 'a-zA-Z0-9' 是一个用于字符转换和删除的 Linux 命令。

具体来说,tr 命令用于字符转换或删除。在这个命令中,-dc 选项结合使用,具有以下含义:

  • -d 选项表示删除指定字符集之外的字符。
  • -c 选项表示使用指定字符集的补集。

字符集 'a-zA-Z0-9' 包含小写字母 a-z、大写字母 A-Z 和数字 0-9。因此,tr -dc 'a-zA-Z0-9' 的作用是删除输入中除了这些字符之外的所有字符。

在这个命令中,openssl rand -hex 12 生成了一个包含 12 个随机十六进制字符的字符串,然后将其传递给 tr -dc 'a-zA-Z0-9',用于删除除字母和数字之外的所有字符。最后,head -c 12 从结果中提取前 12 个字符。

因此,整个命令的目的是生成一个包含 12 个随机字母和数字的字符串。

来自你的消息:

openssl rand -base64 12 |tr -dc '0-9a-zA-Z' |head -c 12 我执行了这个命令,如何让结果自动换行?

来自 ChatGPT 的消息:

如果你想让结果自动换行,可以在 head 命令中使用 -c 选项来指定每行的字符数。例如,你可以将 -c 12 更改为 -c 4,这样结果将每行显示 4 个字符,然后自动换行。

以下是修改后的命令示例:

openssl rand -base64 12 | tr -dc '0-9a-zA-Z' | head -c 12 | fold -w 4

在这个命令中,fold -w 4 将结果分成每行 4 个字符的块,并自动换行显示。

请注意,根据你的终端设置,自动换行可能会受到限制,因此结果可能不会按照你期望的方式显示。

2023-10-20 13:28:17 update

这个问题是 alibaba 的 fastjson 库进行 JSON.toJSONString() 时出现的循环引用问题。

临时解决方案,使用时加上 SerializerFeature.DisableCircularReferenceDetect 的序列化特性。

String reqBody = JSONObject.toJSONString(cidto, SerializerFeature.DisableCircularReferenceDetect);

全局解决就是 new 一个类,在类中执行这个特性就行(类似于全局拦截器的理念),此处不给出了。


生成JSON字符串

来自你的消息:

java11,这个方法打印出来的 json string 为什么是这样的

the result json string is
{"aarch64":{"os_info":{"os_ver":"22.03","os_name":"dkk"}},"x86_64":{"$ref":"$.aarch64"}}
private void testJson() {
        String tmpArch = "x86_64,aarch64";
        boolean multiArch = tmpArch.contains(",");
        JSONObject osObj = new JSONObject();
        JSONObject infoObj = new JSONObject();
        infoObj.put("os_name", "dkk");
        infoObj.put("os_ver", "22.03");
        osObj.put("os_info", infoObj);
        //final String osObjStr = JSONObject.toJSONString(osObj);
        JSONObject customizedObj = new JSONObject();
        if (multiArch) {
            String[] archSplit = tmpArch.split(",");
            for (int i = 0; i < archSplit.length; i++) {
                String archItem = archSplit[i];
                //JSONObject tmpObj = JSONObject.parseObject(osObjStr);
                customizedObj.put(archItem, osObj);
            }
        }
        System.out.println("the result json string is\n" + JSONObject.toJSONString(customizedObj));
    }

来自 ChatGPT 的消息:

这是因为在testJson()方法中,首先创建了一个JSONObject对象osObj,并在其中放置了一个infoObj对象,该对象包含了os_nameos_ver两个属性。然后,如果tmpArch包含逗号,就将其拆分为多个架构,并将每个架构作为键,将osObj作为值放入customizedObj对象中。最后,使用JSONObject.toJSONString()方法将customizedObj对象转换为JSON字符串。

因此,在这个例子中,tmpArch包含x86_64aarch64,因此customizedObj对象包含两个属性,分别是x86_64aarch64x86_64的值是一个$ref属性,它引用了aarch64的值,而aarch64的值包含一个os_info属性,它又包含了os_nameos_ver两个属性。因此,最终的JSON字符串就是:

{
  "aarch64": {
    "os_info": {
      "os_ver": "22.03",
      "os_name": "dkk"
    }
  },
  "x86_64": {
    "$ref": "$.aarch64"
  }
}

来自你的消息:

为什么 x86_64 的值是一个 $ref 属性,并且这个属性的值是 $.aarch64

来自 ChatGPT 的消息:

在本次对话中,我们推测这个 JSON 字符串是使用 Jackson 库将一个 Java 对象转换成的。在这个 Java 对象中,可能存在一个类型为 Map<String, Object> 的属性,其中包含了两个键值对,分别是 x86_64aarch64。其中,x86_64 的值是 $ref 属性,它引用了 aarch64 的值。这是因为在 Java 对象中,x86_64aarch64 实际上是指向同一个对象的引用,因此在转换成 JSON 字符串时,x86_64 的值会被替换成 $ref 属性,指向 aarch64 的值。

$ref 属性的值为 $.aarch64,是因为在转换成 JSON 字符串时,Jackson 库会为每个对象生成一个唯一的标识符,用于标识该对象在 JSON 字符串中的位置。在这个 JSON 字符串中,aarch64 的值是一个对象,它包含了 os_info 属性,因此它的标识符为 $.aarch64。而 x86_64 的值是 $ref 属性,它引用了 aarch64 的值,因此它的标识符为 $.x86_64

来自你的消息:

private void testJson() {
        String tmpArch = "x86_64,aarch64";
        boolean multiArch = tmpArch.contains(",");
        JSONObject osObj = new JSONObject();
        JSONObject infoObj = new JSONObject();
        infoObj.put("os_name", "dkk");
        infoObj.put("os_ver", "22.03");
        osObj.put("os_info", infoObj);
        final String osObjStr = JSONObject.toJSONString(osObj);
        JSONObject customizedObj = new JSONObject();
        if (multiArch) {
            String[] archSplit = tmpArch.split(",");
            for (int i = 0; i < archSplit.length; i++) {
                String archItem = archSplit[i];
                JSONObject tmpObj = JSONObject.parseObject(osObjStr);
                customizedObj.put(archItem, tmpObj);
            }
        }
        System.out.println("the result json string is\n" + JSONObject.toJSONString(customizedObj));
    }

我这样写就能确保生成的 json string 正确

the result json string is
{"aarch64":{"os_info":{"os_ver":"22.03","os_name":"dkk"}},"x86_64":{"os_info":{"os_ver":"22.03","os_name":"dkk"}}}

来自 ChatGPT 的消息:

是的,您的代码能够确保生成的 JSON 字符串符合预期。在您的代码中,首先将 tmpArch 字符串按照逗号分隔成多个架构类型。然后,对于每个架构类型,创建一个新的 JSONObject 对象,并将 osObjStr 字符串解析成一个 JSONObject 对象,然后将这个对象作为当前架构类型的值,存入 customizedObj 对象中。最终,将 customizedObj 对象转换成 JSON 字符串并输出。

这样的代码逻辑确保了每个架构类型都有一个独立的 os_info 对象,而不是多个架构类型共享同一个 os_info 对象。因此,生成的 JSON 字符串中不会出现 $ref 属性,而是直接包含了所有的属性和值。

被 synchronized 修饰的方法:主题

有什么可以帮你的吗

java, openjdk11, 一个语法问题。

被 synchronized 修饰的方法必须是 public void 类型的吗?被 synchronized 修饰的方法有什么作用

被 synchronized 修饰的方法可以是任何方法,不一定是public void类型的。synchronized可用于普通方法、静态方法以及代码块(synchronized(this) 或者 synchronized(锁对象) )。

synchronized用于多线程同步,在一个线程访问被synchronized修饰的方法或者代码块时,其他试图访问该方法或者代码块的线程将会被阻塞,直到该线程执行完该方法才能释放锁,其他线程才能获得锁并执行。这样可以保证共享资源在同一时刻只能被一个线程访问,避免多个线程同时访问共享资源造成竞态条件从而导致数据错乱。

可以是 private 的?

可以,被 synchronized 修饰的方法可以是 private、protected、public 或者默认访问权限。只要是方法,就可以使用 synchronized 来实现多线程同步。但需要注意的是,被 synchronized 修饰的方法在同步过程中会涉及到锁的竞争和释放过程,如果使用不当会导致死锁、性能问题等问题。因此,需要谨慎使用 synchronized。

我现在的场景是,有一个线程池,固定大小 10,里面每一个线程执行的方法都有 method1() 一直到 method4(),其中每个方法都有可能会产生一些异常,此时我封装了一个 sendExceptionMsg() 方法,在各个 method 中都有调用。现在产生的现象是可能多次调用了 sendExceptionMsg() 方法,是因为这个方法不是同步的吗

是的,sendExceptionMsg() 方法如果没有同步,就有可能会被多个线程并发调用,导致出现多次调用的情况。因此,你需要在 sendExceptionMsg() 方法上添加 synchronized 关键字,使得多线程访问该方法时能够被同步排队,避免重复调用:

public synchronized void sendExceptionMsg(String msg) {
    // 处理异常消息
}

这样,当多个线程并发调用 sendExceptionMsg() 方法时,只有一个线程能够进入该方法进行处理,其他线程需要等待该线程执行完毕才能进入。这样就能保证每个异常只会被处理一次,避免出现多次调用的情况。

实际上我只需要这个异常执行一次。在方法的入口有一个终止信号的检测,如果终止信号进来了,我就会停止当前主线程的执行,但是发现流程状态在刚终止的那会是 aborted,但是过了一会又被写成了 exception,原因就是执行了 sendExceptionMsg() 方法

明白了,你的意思是 sendExceptionMsg() 只需要被执行一次即可,不需要每次出现异常都执行一次。那么你可以将 sendExceptionMsg() 方法中的逻辑稍作修改,在第一次被执行时记录一下,以后就直接返回,避免重复执行。例如:

private boolean sendExceptionMsgExecuted = false;

public synchronized void sendExceptionMsg(String msg) {
    // 如果已经执行过,直接返回
    if(sendExceptionMsgExecuted) {
        return;
    }
    
    // 处理异常消息
    
    // 标记 sendExceptionMsg() 已经执行过
    sendExceptionMsgExecuted = true;
}

上述代码中,我们使用了一个布尔变量 sendExceptionMsgExecuted 来记录 sendExceptionMsg() 是否已经被执行过,初始化为 false。在 sendExceptionMsg() 内部,首先检查 sendExceptionMsgExecuted 是否为 true,如果是,则直接返回,避免重复执行。否则,处理异常消息之后将 sendExceptionMsgExecuted 设置为 true。

这样做的好处是可以保证对于同一个异常,sendExceptionMsg() 只会被执行一次,避免重复调用。

你的方法不错,给了我不错的引导,谢谢

不客气,如果还有其他问题可以继续问我,我会尽力帮助你解决。

private boolean sendExceptionMsgExecuted = false; 那这个变量需要是 volatile 的吗

确实,你提到了一个非常重要的点。由于 sendExceptionMsgExecuted 会被多个线程共享(也就是说,一个线程更新了它的值,其他线程需要能够立即看到最新的值),因此必须使用 volatile 关键字修饰它。这样才能保证可见性和线程安全。下面是更新后的代码:

private volatile boolean sendExceptionMsgExecuted = false;

public synchronized void sendExceptionMsg(String msg) {
    if (sendExceptionMsgExecuted) {
        return;
    }
    // 处理异常消息
    sendExceptionMsgExecuted = true;
}

volatile 关键字可以保证 sendExceptionMsgExecuted 变量的可见性和禁止指令重排序。这意味着,当某个线程修改了 sendExceptionMsgExecuted 变量的值之后,其他线程能够立即看到最新的值(而不是使用缓存或者过期的值)。同时,由于使用了 synchronized 关键字修饰 sendExceptionMsg() 方法,可以保证原子性,避免多线程并发执行 sendExceptionMsg() 导致的竞态条件问题。

总之,使用 volatile 修饰 sendExceptionMsgExecuted 变量是非常必要的。

我原本也有一个变量 stopped,用来标记主线程是否有执行过,但是没有被 volatile 修饰,现在出现的现象就是在终止后依然执行了 sendExceptionMsg(),因为我在方法的入口处已经添加了如下代码

// 如果已经终止了就不用再发异常信息了
if(this.stopped){
    return;
}

现在在终止后依然执行了,我分析出就是两个原因造成的,因为可能存在多线程调用这个方法,所以

  1. 我必须使用 synchronized 修饰这个方法
  2. stopped 变量需要是 volatile,在某个线程中更新了其值,其他线程需要立即知晓它的新值

你的分析是正确的。如果 sendExceptionMsg() 方法可能被多个线程访问,那么必须使用 synchronized 关键字对其进行同步,以避免多个线程同时执行这个方法时出现竞态条件。此外,对于 stopped 变量,确实也需要使用 volatile 关键字来保证多线程共享时的可见性和线程安全,这样才能避免一个线程更新了其值,而其他线程依然使用缓存或者过期的值的问题。

下面是更新后的代码:

private volatile boolean stopped = false;

public synchronized void sendExceptionMsg(String msg) {
    if (stopped) {
        return;
    }
    // 处理异常消息
}

public void stopProcess() {
    stopped = true;
}

在这段代码中,使用了 synchronized 关键字对 sendExceptionMsg() 方法进行同步,保证了每次只有一个线程能够访问这个方法。同时,使用了 volatile 关键字对 stopped 变量进行修饰,保证了其在多个线程中的可见性,并禁止了指令重排序,从而避免了多线程竞争带来的问题。

总之,对于多线程并发访问的情况下,关键变量必须使用 volatile 关键字修饰,以确保其在不同线程中的可见性和线程安全。同时,使用 synchronized 关键字对关键方法进行同步,避免多线程访问时出现竞态条件。

那么这样的话,上面的变量就可以不用定义了,

private boolean sendExceptionMsgExecuted = false;

就这个变量。因为 stopped 已经实现了他的功能

是的,你说得没错。如果在 stopProcess() 方法中将 stopped 变量设置为 true,那么在 sendExceptionMsg() 方法中检查 stopped 变量是否为 true,就可以达到和 sendExceptionMsgExecuted 变量相同的效果了。

因此,如果使用了 stopped 变量,就可以省略 sendExceptionMsgExecuted 变量了。下面是更新后的代码:

private volatile boolean stopped = false;

public synchronized void sendExceptionMsg(String msg) {
    if (stopped) {
        return;
    }
    // 处理异常消息
}

public void stopProcess() {
    stopped = true;
}

在这里,使用了 volatile 关键字对 stopped 变量进行修饰,保证了其在多个线程中的可见性和线程安全。同时,在 sendExceptionMsg() 方法中,检查 stopped 变量是否为 true,如果是,就直接返回,避免了多线程访问时可能出现的异常情况。

总之,使用 stopped 变量替代 sendExceptionMsgExecuted 变量是可行的,并且可以减少代码的复杂度。

ok 谢谢你的指导

不客气,祝你的程序开发顺利!