1. 一个 CPU 核心,在一个具体的时间点,注意是时间点,比如 某 xxx 纳秒的时候,是仅仅有一个线程是运行状态,而其它 9 个都不是. 建议复习一下 线程的生命周期. 另外,线程是你代码执行的容器,并不是你代码本身. 当你代码在某个线程中执行完后,线程就销毁了. 而线程池则是让你代码执行完后,线程并不销毁,而是重复使用. 再就是线程安全主要指的是内存中变量的读写在同一时刻只有一个线程可以操作.
2. 并发数超过线程数后,请求确实是排队中的. 只不过每个请求的处理时间很短,基本毫秒级别就结束了. 打个比方,某个请求处理耗时 5ms,那 1 个线程 1 秒就可以处理 200 个请求.理论上 10 个线程就是 2000 个请求,但线程切换是也是要消耗时间的.所以实际上达不到 2000,也正是因为线程切换要消耗资源和时间所以线程数不是越大越好.
尽管总结的字数很多,但看起来没有触及到根本问题. 需求调研没有做细致,缺少架构设计能力.任务拆分不合理.
需求调研不细致,才导致各种 "万万没想到"; 才会让你低估项目难度, 进而导致任务分配给了不合适的人身上.
缺少架构设计能力,4 个项目,老框架,中间件,插件,设备,按理说应该先收集评估相关技术,然后设计整合的架构方案.然而并没看到,而是直接分配任务了. 也会导致任务分配给不合适的人.
制造业工厂一个工厂也就一个 IT 部门,维护一下网络,电脑等,即便是程序员基本也是写点小脚本,主要还是与外包沟通需求,跟进项目进度为主.
但有一类公司,非标自动化公司,无论大小,基本都会有那么几个软件开发,目前先进一点的用软件+板卡的形式控制设备,low 一点的与 PLC 交互做采集,做所谓的数字孪生或者智能工厂
我来说一下 1/1000 DDD
1. 问题领域识别: 明确你面对问题所在领域. 例如 你要完成一个用户登录功能. 那么 往大了说,这属于 "信息安全领域"
2. 领域建模: 将这个领域中的处理模型搞清楚,并映射为对应的计算机语言设计,例如面向对象设计,将这个领域中的对象设计出来.
所以,起始最核心的是 "领域专家 " 这个角色,他有充分的专业知识和经验 能够给最初设计给出完整的领域知识的指导. 而程序员通常是计算机的"领域专家",并不是信息安全领域的,也不是 财务方面的,也不是仓库,物流,运营方面的. 如果领导让程序员去 DDD 本身就不是靠谱的事.
再退一步,其实实际工作中,"领域专家" 90% 情况下不存在.大家几乎都是自己岗位的熟练工而已....如果不信可以找公司会计问问,如果要开发一个 财务系统,希望他给你讲讲财务领域的知识,同时让他给设计建议,保证你最后实现了,也就你们公司能用. 根本达不到 财务领域 通用的程度.
一堆人费劲心思提出了这么个 Promise 规范,解决异步带来的麻烦, 然后你要在这基础上硬生生的在退回原始方式....
个人看法,单纯讨论语言没意义. 要看你发展的领域. 如果还是 Web 方向,毫无疑问是 Java.
如果但是如果是工业自动化领域,毫无疑问是 C# . 各家设备厂商提供的 SDK 基本优先 C#版或者 Dll
首先,你可以这么写程序,java 并没有限制你不能这么干.
不过,你要明白 new Object() 等于开辟了一块内存区域,而方法调用的时候,方法中的上下文(this) 可以等同于 这块内存(不严谨). 举例:
``
public class MyObject{
private String name ;
public MyObject(String n){
this.name=n;
}
public void getName(){
return
this.name;
}
}
MyObject obj_1 = new MyObject("张三"); // 开辟了 内存 A
MyObject obj_2 = new MyObject("李四"); // 开辟了 内存 B
obj_1.getName(); // 张三
obj_2.getName(); // 李四
``
那么,如果全部是 static 方法,可以自行查阅一下 static 方法内存怎么管理的. 然后上述功能如何体现.自己写一下可能就能理解这么干的优点了.
你可以看看 JeecgBoot ... 功能更强一点.
另外你可以将生成代码的路径直接指向源码目录,然后配合 JRebel 这种热更新的工具就能达到你期望的目标.
当然生成的代码的目录结构与源码目录结构可能不同,这时候你可以自己搞个目录监控,将生成的源码自动拷贝到源码对应的目录下即可.
普通的写写逻辑你可以不关心原型链,无非就是声明个变量,if-else ,for 循环。
但是,如果你是处在核心研发团队,做框架,并且还提供个其他人用,如果你不懂原型链,那肯定不敢用你,鬼知道你把 “this” 给了谁。
如你所说:“其实时间都是消耗在网络 IO 上” 线程是不解决 IO 问题的,你需要的是 异步 IO 处理机制。一个线程同时处理多个 IO ,而不是一个线程处理一个 IO 。
代码 "臃肿" 并不是问题. 个人看法是 耦合度太高.无法应对需求变动,建议参考其它用户,权限,角色管理系统. 我个人认为存在的问题有这么几个
1. login 方法中的参数,未做比较严格的校验,如果客户端传入了 10 万字符长度的,你这里会不会卡?
2. 是否可以将参数校验单独提取为一个 方法? validator
3. 用户黑白名单与角色的功能是写死的,如果需求变动,是需要改代码的. 如果允许可以使用 apache shiro 这种成熟的权限框架,如果觉得重,也务必将 授权,鉴权 独立为两个模块,方便扩展.
重要的事情 吼三遍
协程的目的不是提升性能! (当然比纯线程还是有提升的)
协程的目的不是提升性能!
协程的目的不是提升性能!
协程是简化了多线程开发难度!
协程是简化了多线程开发难度!
协程是简化了多线程开发难度!
可以用 多线程版完成一个 3 个生产者,2 个消费者程序,再用 Go 的协程+channel 实现一版,就更能体会到了, 更像是一种语法糖. 其意义在于从语法层面降低: 多线程 /异步 开发门槛.
C#吧,Winform ,拖拽个界面。使用 HTTP 协议与 Java 通信交换数据,例如 Flurl ;
然后 Java 端内置一个 Jetty 作为 web 服务;
缺点: 仅适用于 Windows ,无法跨平台;界面稍微不注意会很丑
优点: 快,Java 端逻辑可以完全复用。
@
pkoukk 或许你根本不理解什么是 "计算机语言" 手动狗头
1. 你认为的生态如何重要了?
2. 那 Go 语言的设计逻辑与 Java 差别在哪里了?
3. 各有适应场景又如何解释?
请赐教
在这里我一直感谢我之前的老板,不断的强调:"语言只是工具,核心是动态模型". 如果理解这句话,从 Python 转 Go, 一周就可以上手了.
语言所具备的几个基本点:
1. 变量
2. 类型
3. 条件分支 /循环
4. 函数
这些内容,只要会了一门语言,学一门新语言应该说是 1,2 天熟悉一下就可以了. 即便一下子记不住,后续回过头来查一下即可.
可能需要花点时间的也就是 协程 ,但是如果你多线程和异步的概念很扎实的话,协程也很简单. 而多线程,异步就是所谓的 "动态模型" 而这部分内容是与计算机语言无关的.
1. 办一个禅修学院,真正教授正确修行方法的地方.
2. 去西藏某个寺院出家
String contenxt = File.read("path");
首先,代码运行是在 CPU 中执行;
其次,CPU 再向 IO 设备,例如内存,硬盘,或者网络发出读写指令;
最后,CPU 等待 IO 设备反馈;
此时,问题就来了,CPU 以纳秒为单位, 无论是内存,硬盘,还是网络,尤其是网络 以毫秒为单位,相差了多少倍,请自行换算.
就意味着,如果是同步 IO 模型,那在 CPU 发出读写指令后,会令当前线程
阻塞
阻塞
阻塞
等收到设备数据后,当前线程,继续往下执行.
针对以上过程,所谓的 "性能" 也好 "吞吐量" 也好,绝大多数浪费在了 CPU 等待 IO 设备反馈的时间上了. 那如何解决这个问题呢?
请自行阅读
https://segmentfault.com/a/1190000039898780 5 种 IO 模型.
所以如果想提高 "性能" 两方面入手:
1. 框架本身基于更高效的 IO 模型
2. 业务层代码,也使用更高效的 IO 模型库:
比如将 同步 IO 代码
String contenxt = File.read("path");
更换为 异步 IO 代码
String contenxt = await File.read("path");
async / await 都是语法糖,语法糖,语法糖,只是语言层面为了开发人员简化书写提供的便捷写法. 而底层 IO 机制无外乎前文中的 5 种 IO 模型
.idea,.gradle 目录已经移除了.
@
danc 我现在仅仅算是用基恩士上位链路协议跑通阶段. 后面肯定扩展其他协议. 但这方面网上的协议资料不好找,你可以分享一下关于协议方面的资料吗