读程序员的制胜技笔记10_可口的扩展

【GAMES201学习笔记】物质点法入门 《GAMES201》 学习笔记 阅读详情

1. 可扩展性

1.1. 土耳其的一句谚语:“路到眼前必有车”

1.1.1. “别为还没到来的事情烦恼”

1.2. 单纯的高性能并不能使一个系统具有可扩展性,你需要让所有方面的设计都得能够迎合越来越多的用户

1.3. 没有一个单一的方案可以解决我们所有的问题,我们需要把所有用来解决问题的方法放在我们的工具箱里,根据手头的问题来使用正确的方法

1.4. 从系统的角度来看,提升可扩展性意味着投入更多的硬件来让系统变快

1.5. 从编程的角度来看,可扩展的代码可以在面对日益增长的需求时保持网站的响应速度不变

1.6. 某些代码所能提供的负载是有上限的,而编写可扩展代码的目标就是尽可能地提升这个上限

1.7. 从零开始设计一个完全可扩展的系统是可能的,但实现这一目标所需的努力和时间以及你得到的回报都被“产品需要快速上线”这件事给掩盖了

1.8. 实现可扩展代码的第一步是剥离阻碍实现可扩展的不良代码

1.8.1. 这样的代码会产生瓶颈,导致即使你增加了更多的硬件资源,代码运行仍然缓慢

1.9. 不能让一个CPU核心在1秒内运行比其时钟频率更多的指令

1.10. 增量标识符会泄露你的应用信息

2. 不要使用锁

2.1. 锁定(locking)是一个让你能够写出线程安全代码的特性

2.2. 线程安全(thread safe)的意思是一段代码即使被两个或多个线程同时调用,也能稳定地工作

2.3. 在很多情况下,简单的原子增量操作并不足以使你的代码成为线程安全的

2.4. 你的实例也可能被你的代码之外的一些代码锁定。这可能会导致不必要的延迟甚至死锁,因为你的代码可能在等待其他代码运行完成

2.5. 死锁

2.5.1. 获取资源并等待释放另一个资源结果就像一个无限循环,等待着一个永远不会被满足的条件

2.5.2. 除了清楚地了解代码中的锁机制之外,没有其他解决死锁的“灵丹妙药”,但一个好的经验法则是总是先释放最近获得的锁,并尽快释放

2.5.3. GO编程语言的通道(channel)特性仍然有可能出现死锁,只是可能性比较小

2.6. 确定你使用的共享数据结构是否有无锁的替代方案

2.6.1. 无锁结构可以被多个线程直接访问而不需要任何锁

2.6.2. 无锁结构甚至可能会比有锁的结构慢,但它们的可扩展性会更好

2.6.3. 使用无锁结构的一个常见场景是共享字典(shared dictionary),它在某些平台被称作图(map)

2.6.4. 缓存数据结构时可以使用无锁的设计

2.7. 字典不是线程安全的,但线程安全只在有多个线程修改一个给定的数据结构时才应该考虑

2.8. 所有没有副作用的只读结构都是线程安全的

2.8.1. 如果一个函数对其作用域之外的东西产生了影响,就是产生了副作用

2.8.2. 一个没有任何副作用的函数无论运行多少次,其环境都不会有任何变化

2.8.3. 没有副作用的函数被称为纯函数(pure function)

2.8.3.1. 纯函数有一个好处,它们是100%线程安全的

2.9. .NET提供了两套不同的线程安全数据结构

2.9.1. 以Concurrent开头,使用了“短命”(short-lived)的锁

2.9.1.1. 这套数据结构并不都是无锁的
2.9.1.2. 虽然它们依然使用锁,但它们是被优化过的,锁的持续时间会很短,保证了其速度,而且它们可能比真正的无锁替代方案更简单

2.9.2. Immutable

2.9.2.1. 其中原始数据从未改变,但每个修改操作都会创建一个带有修改内容的新数据副本
2.9.2.2. 在有些情况下,它们可能比Concurrent更合适

2.10. 双重检查的锁

2.10.1. 确保只创建一个实例

2.10.1.1. C#
class Cache {
  private static object instanceLock = new object();  ⇽--- 用来锁定的对象
  private static Cache instance;  ⇽--- 缓存实例值
  public static Cache Instance {
    get {
      lock(instanceLock) {  ⇽--- 如果有其他线程在这个代码块里运行,其他所有调用者都会在这等待
        if (instance is null) {
          instance = new Cache();  ⇽--- 对象被创建,也只被创建一次
        }
        return instance;
      }
    }
  }
}
2.10.1.2. 对Instance属性的每次访问都会导致它被锁定,这会产生不必要的等待时间
2.10.1.3. 为实例的值添加二次检查(secondary check)
2.10.1.3.1. 如果实例已经被初始化,那么在进行锁定之前返回它的值
2.10.1.3.2. 如果实例还没被初始化,那么只进行锁定

2.10.2. 双重检查锁

2.10.2.1. C#
public static Cache Instance {
  get {
    if (instance is not null) {  ⇽--- 注意C# 9.0中基于模式匹配的“not null”检查
      return instance;  ⇽--- 返回实例而无须锁定任何内容
    }
    lock (instanceLock) {
      if (instance is null) {
        instance = new Cache();
      }
      return instance;
    }
  }
}
2.10.2.2. 不是所有的数据结构都可以进行双重检查锁
2.10.2.3. 不能对字典的成员进行双重检查
2.10.2.3.1. 当字典被操作时,不可能在锁之外以线程安全的方式从字典中读取数据

2.10.3. LazyInitializer辅助类

2.10.3.1. 使用LazyInitializer的安全初始化
2.10.3.1.1. C#
public static Cache Instance {
  get { 
   return LazyInitializer.EnsureInitialized(ref instance); 
 } 
}
2.10.3.2. 让安全的单例对象初始化(safe singleton initialization)变得更加容易

2.10.4. 双重检查锁场景的替代方案

2.10.4.1. C#
class LimitedList<T> {
  private List<T> items = new();
  public LimitedList(int limit) {
    Limit = limit;
  }
  public bool Add(T item) {
    if (items.Count >= Limit) {  ⇽--- 锁外的第一次检查
      return false;
    }
    lock (items) {
      if (items.Count >= Limit) {  ⇽--- 锁内的第二次检查
        return false;
      }
      items.Add(item);
      return true;
    }
  } 
  public bool Remove(T item) {
    lock (items) {
      return items.Remove(item);
    }
  } 
  public int Count => items.Count;
  public int Limit { get; }
}
2.10.4.2. 如果不在枚举(enumeration)之前完全锁定列表的话,就不可能在直接索引访问上提供线程安全的枚举
2.10.4.3. 该类只在计算项数时有用,对访问各项没用
2.10.4.4. 访问Count属性操作本身是相当安全的,所以我们可以在双重检查(double-checked)中使用它来获得更好的可扩展性

3. 拥抱不一致

3.1. 平台出于可扩展性的要求,能够容忍一定程度上的不一致

3.2. 数据库提供了大量的特性来避免不一致(inconsistency)

3.2.1. 锁、事务、原子计数、事务日志、页面校验(page checksum)和快照等

3.2.2. 为那些根本不应当检索到错误数据的系统而设计的

3.2.2.1. 银行工作系统、核研究机构及相亲交友软件系统

3.3. 一些不可靠的场景在其他方面,比如性能和可扩展性方面有明显的优势

3.3.1. NoSQL放弃了传统关系数据库系统的某些一致性功能,获得了性能、可扩展性和潜在的回报

3.4. 最终一致性是指你依然能确保一致性,不过需要一些延迟

3.5. 脏数据

3.5.1. 如果一个事务开始向数据库写入一些数据,但写入操作还没完成,这个阶段的数据就被认为是脏数据

3.6. NOLOCK决定了读取它的SQL引擎可能是不一致的,会包含来自尚未提交的事务的数据

3.7. NOLOCK作为查询提示(query hint)出现的原因

3.7.1. SQL中的SELECT查询在表里并不持有锁,但是它仍然会被另一个事务所阻塞

3.7.2. NOLOCK查询提示可以让一个查询读取脏数据(dirty data),但作为回报,它不需要在意其他查询或事务持有的锁

4. 不要缓存数据库连接

4.1. 开启一个单独的数据库连接,并且把它在代码里共享是一个相当普遍的错误操作

4.2. 在运行查询的时候,查询需要不同的事务范围(transaction scope),并且当你试图将单个连接同时用在多个查询时,它们之间会产生冲突

4.3. 当你以为你用的是一个新建立的连接时,其实你用的只是从连接池检索出的一个已经建立的连接

4.4. 以ORM的形式

4.4.1. 现代对象关系映射(object relational mapping,ORM)工具以库的形式存在,可以通过提供一组完全不同的复杂抽象(比如Entity Framework)来掩盖数据库的复杂性

4.5. 你根本不用关心连接的开启与关闭,框架可以自动帮你去处理

4.6. 它在必要时开启连接,并在用完后关闭连接

4.7. 你可以在一个请求的整个生命周期中使用一个与Entity Framework共享的DbContext单个实例

4.8. 你可能不希望在整个应用里使用单个实例,因为DbContext并不是线程安全的

5. 尊重单体

5.1. 微服务背后的逻辑很简单:如果我们把代码分割成单独的自托管项目,那么将来将这些项目部署到独立的服务器会更容易,操作空间很大

5.1.1. 这个逻辑暴露出的问题是增加了复杂性

5.2. 即使只有单个CPU核心,我们也可以实现很好的可扩展性,更不用说在单个服务器上了

5.3. 选择单体架构,也是你本地的代码原型下一步发展的自然结果

5.4. 不要让微服务使新项目复杂化

5.4.1. 只有当使用微服务的优点盖过缺点时才考虑使用微服务

6. 不要使用线程

6.1. 扩展性不仅仅关乎更多的并行化

6.1.1. 它也关乎节约资源

6.1.2. 你不能使用超过现有的全部内存的空间,也不能让CPU占用超过100%

6.2. “抢占”(preemption)

6.2.1. 过去单核CPU的多任务工作方式

6.3. 由于操作系统安排线程的方式,在线程池中拥有比CPU核心数量更多的线程只是一种获得更多CPU利用率的粗糙方法,甚至会损害可扩展性

6.4. 利用等待I/O的时间的一个更准确的方法是使用异步I/O

6.4.1. 异步I/O是非常有前途的

6.5. 异步I/O是很明确的:无论你在哪里有一个wait关键字,都意味着线程将等待回调的结果

6.6. 只要你使用的是一个支持异步调用的框架,将现有的代码升级到异步I/O代码也是很简单的

6.7. 异步函数实际上不需要用后缀Async来命名,但这个惯例可以帮你标识需要你等待的东西

6.7.1. 你必须浏览源代码,找出一个异步函数是否真的是异步的

6.8. 函数声明开头的async关键字只是意味着你可以在这个函数中使用await

6.9. 所有的异步函数必须返回一个Task或者Task<T>

6.9.1. 一个没有返回值的异步函数也可以有一个void返回类型,但这明显会引发一些问题

6.9.2. 没有返回值的异步函数应该总是使用Task来作为返回值

6.10. await关键字的作用是让下一行表达式只有在它前面的表达式运行完毕后才会被执行

6.11. 异步代码的问题

6.11.1. 无I/O,不异步

6.11.1.1. 如果一个函数没有调用异步函数,它就不需要是异步的
6.11.1.2. 异步编程只有在与I/O绑定操作一起使用时才有助于提升代码的可扩展性
6.11.1.3. 你得时刻保持清醒,明白你为什么想把某个函数改写成异步的

6.11.2. 不要把同步和异步混为一谈

6.11.2.1. 在同步代码中调用异步函数的最大问题是,由于异步函数中的其他函数依赖于调用者代码运行完成,它可能会导致死锁,异常处理也可能跟你想的不太一样,因为它将被包裹在一个单独的AggregateException里面
6.11.2.2. 并非每个函数都适合异步。

6.12. 异步多线程

6.12.1. 多线程和异步并不相互排斥,你可以两者兼得

6.12.2. 异步编程可以使一些多线程代码更容易编写,但它既不能完全替代多线程编程,也不能提高代码的可扩展性

6.12.3. 用异步语法编写的多线程代码仍然是普通的多线程代码,它不像异步代码那样节约资源

双目立体成像(一)双目图片生成点云 利用左右目图片生成点云 阅读详情

相关推荐

从ADRV9002到ADRV9003:手把手教你移植FPGA驱动,避开那些官方没说的坑

本文详细介绍了从ADRV9002到ADRV9003的FPGA驱动移植实战指南,重点解析了两者在硬件架构上的关键差异,如通道配置和DPD功能的移除。通过提供完整的移植步骤、调试技巧和性能优化建议,帮助工程师避开官方文档未提及的常见陷阱,实现高效驱动开发。

weixin_28738397的博客 173

读程序员的制胜技笔记15_读后总结与感想兼导读

读后总结与感想兼导读

lyingSeven的博客 181

Python实现安居客新房数据抓取简易版

本文介绍使用Python爬取安居客新房楼盘数据的方法,重点针对三四线城市。通过分析移动端H5页面结构,采用滚动加载方式获取推荐楼盘列表(class="recomm-list"),从中提取楼盘ID并拼接详情页链接。代码展示了如何解析HTML标签获取楼盘名称、状态、价格、户型等基本信息,并处理图片URL。爬取过程涉及一个一级页面和两个二级页面,同时提到可能遇到的验证码问题将在后续处理。核心代码使用BeautifulSoup解析HTML,requests发送请求,并将数据存入MySQL数据库。

qq_37604998的博客 473

读程序员的制胜技笔记02_算法与数据结构

算法与数据结构

lyingSeven的博客 234

从零到一:基于GeneMark-ES/ET的新基因组注释实战指南

本文提供了一份基于GeneMark-ES/ET的新基因组注释实战指南。详细介绍了从环境搭建、数据准备到核心运行的全流程,重点解析了ES(从头预测)与ET(结合RNA-Seq证据)两种模式的选择与操作,并分享了Perl模块依赖、并行处理等常见问题的解决方案,帮助生物信息学研究者高效完成基因预测工作。

weixin_29266647的博客 206

Pyinstaller 打包 Pyzbar 时缺失 DLL 文件的排查与修复指南

本文详细解析了使用Pyinstaller打包Pyzbar库时,因缺失关键DLL文件导致程序闪退的常见问题。文章提供了从问题复现、错误诊断到最终修复的完整解决方案,核心在于通过修改.spec配置文件,手动将缺失的libzbar-64.dll等文件添加到打包过程中,确保生成的可执行文件能独立运行。

wdx012345的博客 502

读程序员的制胜技笔记06_测试(下)

测试

lyingSeven的博客 125

在Rviz仿真环境中搭建传送带

<geometry><material>

qq_58268456的博客 934

读程序员的制胜技笔记05_测试(上)

测试

lyingSeven的博客 125

手把手实现STM32+ESP8266+原子云服务器+手机APP应用——第三节-编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯

接上一篇,本节使用原子云服务器。编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯。使用的硬件包括:STM32F103(任意其他款系列也可以的)、正点原子ATK-ESP8266、LED灯。实现编写STM32程序代码来传输单片机数据到原子云服务器和手机APP进行显示,同时通过手机APP和原子云服务器可以远程控制单片机,例如本节实现远程点/灭灯,以此可以扩展开发更多的功能。本专栏本系列的相关文章可查看下面链接:

嵌入式阿齐Archie 8409

scp 出现Permission denied错误 解决方法

第一种说辞(来源于网络),说是scp涉及root远程登录,默认是没有打开的,只需要把配置文件中的permit打开即可。最后scp的时候发现还不行,只需要将其scp的服务器用户名 修改为root即可。第二种解决方案,将scp 传输的服务器用户名改为root即可。(这是最基本的,一开始我忽视了这个问题,导致一直scp不了)window系统下,向ubuntu操作系统 scp传输文件。

码农研究僧的博客 6727

读程序员的制胜技笔记04_有用的反模式(下)

有用的反模式

lyingSeven的博客 559

热更新方案 HybridCLR 学习教程 |(一)原理及准备工作

前面文章介绍了热更新相关的知识,包括使用xLua实现热更新实战等 那本文就来介绍一下 热更新方案 HybridCLR(代号wolong,原huatuo)和基本使用方法。 若是想了解更多关于HybridCLR的东西也可以去 官网 详细查阅。

努力前行,总会成为自己心中的那道光 2万+

程序员的进阶之路

原文链接: https://dsx2016.com/?p=719 微信公众号: 大师兄2016 非器非术非道,仅聊聊一些方向. 分阶 很多事物都可以按进度和阶段来划分,如程序员的小白,初级,中级和高级. 但是这种层次之分也有内外之别. 公司招聘的中高级职位取决于业务的能力需求和薪水发放的高低,是市场的宏观定义. 个人的中高级之分在于自我的能力进阶,来源于技术但不仅仅限于技术,...

大师兄 859

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Android程序员该如何进阶?这份Android开发核心知识点笔记请收好

开头 无论你是在校的大学生,还是职场人,这篇文章都适合你 文章末附带资深架构师必须掌握的技能 1. 我们生活的每天都面临着很严重的挑战 虽然目前看起来我们都在做着自己的事情,一切在顺利的进行着,但是,实则不然,我们每个人的身边或是自身已充满着“危机”,这里说的危机是指你的自身价值可替代性。 不管你做什么,自己的不可替代性是最重要的。那么如何解释这点呢?细心想想,不难。 从技术方面来讲 你的个人技术深度在你的职业生涯前期是很占据优势的,如果你能在前3年做到技术出众,在深度上比同行的造诣更深一层的话,那么你

Java进阶营的博客 454

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

蓝桥杯C++竞赛的制胜法宝——智能化编程工具助力高效开发

最新接入DeepSeek-V3模型,点击下载最新版本InsCode AI IDE 标题:蓝桥杯C++竞赛的制胜法宝——智能化编程工具助力高效开发 引言 随着信息技术的飞速发展,编程竞赛逐渐成为培养和选拔优秀程序员的重要途径。蓝桥杯作为国内知名的编程竞赛之一,吸引了众多高校学生和编程爱好者的积极参与。然而,面对复杂的算法题和严格的评分标准,如何在有限的时间内编写出高质量的代码成为了参赛选手面临的最大...

inscode_048的博客 991

【1024编程挑战赛2025全解析】:揭秘顶尖程序员破局制胜的5大核心策略

掌握1024编程挑战赛汇总2025核心策略,快速提升算法实战能力。涵盖高频考点、优化技巧、团队协作模式与真实赛题解析,助力程序员高效破局。五大方法直击备赛痛点,提升竞赛表现,值得收藏。

DevPath的博客 1166

如何规划程序员的未来职业路线?

在互联网时代,互联网真的给我们带来了极大的便利性。而为互联网时代撑起半边天的就有那么一群人,他们被称为程序员。像阿里巴巴、腾讯、百度等等大咖,它们的成功最近都离不开程序员,而他们也不像马云、马化腾那么有名,更多的就是在背后默默无闻的付出。 在经过多年编码的生涯,很多程序员都会对未来感到很迷茫,他们不知道该如何选择前方的道路。创业?继续打工?或者是其它。。。 小编前几天在网上看见了这样一张图片,对于处在迷茫期的程序员来说,或许对你们能有帮助。 上图中,使用了很多的术语,这里先做解释,只有大家都明

weixin_43298663的博客 517

阿里技术官亲述为啥30岁是程序员的“坎”?程序员职业规划之道

程序员生存、成功、制胜的法则源自IT精英的职业发展秘诀热爱工作,享受生活。

jjc4261的博客 261

程序员必备能力——晋升之道

程序员必备能力——晋升之道 从我认识的程序员中,包括我的团队中,有不少很久都没有晋升过。他们维护着已经再熟悉不过的模块,能迅速定位bug所在代码行数,在他们当中有部分人热爱coding,享受debug带来的成就感,但是绝大部分的程序员并不是他们热爱,而更多的是被迫。 你们有认识这样的人吗?我想你肯定已经在点头了,这种情况竟然出乎意料的常见。如果你不想在这条死胡同里终老,你就应该主动点。 标题01提升自我价值,提高自身核心竞争力 在2017年发布的《中美毕业生就业对比研究》报告中,我们可以发现就业总量和就业

qq_45131570的博客 226

程序员迷茫:30岁以上的“大龄程码农”出路在哪?java码农该怎么办?

在国内的大环境下,很多软件的实现代码都是拿来主义,特别是在一些小公司做项目时,很多程序员的代码都写得很初级、从网上东拼西凑找来一些现成的代码,尽快实现基本功能就行,什么性能、可维护性、可扩展性都不太管,做完交活便是。软件开发的技术、工具在不断进化,特别是在一些新技术、新工具方面,30岁以上的人未必比20几岁的人强很多,并且,如果他们不学习,可能掌握的一些技术经验会慢慢被时代所抛弃,而年轻人的学习速度和接受能力明显更有优势。时间长了,我们就被固定在一个“敲代码”的坑里,一干就是10年。

老男孩的架构路 3972

2024金三银四求职大战:程序员如何脱颖而出?

面对金三银四的求职竞争,如何才能脱颖而出?本文从夯实编程基础、精深技术栈、提升解决问题能力、培养沟通和协作能力、保持自我学习能力等六个方面,为程序员提供实用的求职建议,并附上金三银四求职备战指南,助力程序员在求职战役中技压群雄,收获理想offer!

silenceallat的博客 1089

2020程序员VS码农,“金三银四”春招指南

从代码实现层面看,在功能刚开始开发时,这两个设计区别不是很大,但随着系统演进、越来越多的功能加入,继承关系带来的耦合会导致模块之间关系越来越复杂,牵一发而动全身,终究有一天哪怕只做很小的改动,也将成为压死骆驼的最后一根稻草。 这次重构的成果是代码量由43K减少到15K,扩展新的接口能力不再需要修改已有代码。我想,这或许就体现了码农和程序员的区别吧。 建立知识体系 1.Android高级架构师筑基技能 内容 java泛型 java注解 并发编程 数据传输与序列化 java虚拟机原理 .

m0_61041309的博客 194

《奔跑吧,程序员:从零开始打造产品、技术和团队》 读书笔记

本书以软件工程师出身的创业者的角度,全面介绍了公司该如何打造产品、实现技术和建立团队,既是为创业者打造的一份实用入门指南,又适合所有程序员系统认识IT行业。书中内容分为三部分——技术、产品和团队,详细描绘创业的原始景象,具体内容包括:创业点子、产品设计、数据与营销、技术栈的选择、整洁的代码、软件交付、创业文化、招兵买马,等等。 本书适合所有程序员。

发现问题,面对问题,分析问题,解决问题,总结问题 2716

Android开发无线调试,来自阿里巴巴佛系安卓程序员的指南

5.电脑上打开命令提示符,敲入以下命令:(需要打开手机的开发者模式和usb调试)adb connect a.b.c.d//如果不输入端口号,默认是5555,自定义的端口号必须写明,对应第1步中自定义的端口号,例如:a.b.c.d:5554(手机查看ip地址:设置-关于手机-状态信息-ip地址)6.关闭无线调试1)进入 Android 设备终端中:$./adb shell2)切换为 Android 设备的 root 用户:$ su -3)设置 adbd 服务的指定端口号:# setprop service.a

2401_83621004的博客 1171

36 岁应聘 Android 程序员岗位,竟因年龄问题被领导直接拒绝…

在社交媒体上,李国庆表示,35到40岁的年龄限制其实只针对于互联网大厂,35岁的职场人士不需要太当回事,反而这段时间是职场人士自我增值、发展的黄金时期。网友表示:别说互联网企业了, 很多社工、公务猿岗位都是只要35岁以下的, 自己带头限制, 还要搞延迟退休, 难道过完35岁就是65岁吗?就业年龄歧视不解决, 出事早晚的事情。

2301_76190858的博客 949

35岁,滴滴司机想当程序员,烦透了,可父母力阻我辞职,怎么办?

前言 情况是这个样子的,我今年35岁,男,在滴滴做司机(之前是程序员),虽然工资收入都还可以尽管上了年纪但是我想跳槽去字节跳动试一下,再次干会老本行! 我是学java的后面转的Android,985本硕,这几年我在滴滴干的还可以,但是一成不变的生活和工作!我想改变一下! 我现在有房无贷款,有家庭。父母不需要我养老。 现在最大的阻力在父母,他们干教师一辈子极力阻止我辞职! 即使在这样的情况下我还是选择了辞职!因为哪怕年纪到了,压力更大了,我也想好好为自己努力一次! 新的开始(面试) 一面:1h 1. 单例模

wzh19950826的博客 9146
上一篇: 读程序员的制胜技笔记09_死磕优化(下)
下一篇: 读程序员的制胜技笔记11_与Bug共存(上)
躺柒
博客等级 码龄4年 7004粉丝 1317原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值