精华内容
下载资源
问答
  • 6 大原则是内功心法,23 种设计模式是武术套路,它们的本质是为了更好地面对需求变化。 很多人对于设计模式背诵滚瓜烂熟,但是却没有办法评价自己代码质量,尤其是根据自己想法整了一大

    程序员都知道编程有 3 大类:面向过程、面向对象、面向函数。面向对象是被讨论的最多的,个人认为,这是因为 Java 之类的编程语言有强大的用户基础,本质还是因为比较符合人的直觉。

    说到面向对象,大家可能就会很快想到了 23 种设计模式,可只有少部分人会想到面向对象的 6 大原则,所以本文我分享一下我对于 6 大原则的看法。

    6 大原则是内功心法,23 种设计模式是武术套路,它们的本质是为了更好地面对需求的变化。

    很多人对于设计模式背诵的滚瓜烂熟,但是却没有办法评价自己的代码质量,尤其是根据自己的想法整了一大堆设计模式之后,很难分辨自己是规范编程还是过度设计。

    其实,设计模式是立足于 6 大设计原则上的。

    6 大设计原则对应 6 个规则,取首字母缩写就是 SOLID 。

    1. 单一职责原则 (Single Responsibility Principle)

    描述:一个类只有一个引起修改的原因。

    理解:我们都知道要软件开发要解耦合,减耦合的理想状态就是一个类只负责一个功能。

    软件开发要做好拥抱变化的准备。

    比如,1 个月前,你做了一个类,负责用户模块。

    后来需求变动,登录增加了微信账号登录,你得改你的用户模块。

    后来需求变动,注册增加了手机动态码验证,你的修改你的用户模块。

    后来需求变动,登录增加了github 登录,你的修改你的用户模块。

    后来需求变动,登录增加了weibo 登录验证,你得修改你的用户模块。

    后来需求变动,… 你已经麻木了。

    你会发现,你的用户模块越来越臃肿了。

    但是,如果你一早就实现 2 个类,一个负责登录,一个负责注册。

    那么登录需求的变化不会影响注册的代码,反之已然。

    虽然,代码没有减少多少,但你可以明确感受到职责分明,所以开发会更轻松一点。

    在这里插入图片描述

    2. 开闭原则 (Single Responsibility Principle)

    描述:一个软件实体,应该对扩展开放,对修改关闭。

    理解:很多人可能对这个概念感到有些玄乎,其实很好理解的。

    假设你是乙方,你给甲方的交付物是一个 SDK,有一天客户想要增加一个功能,现在有 2 种方案可以选择:

    1. 你重新开发一个新的 API 供客户调用。
    2. 建议客户利用现成的 SDK 扩展一个新的 API 自己解决问题。

    说具体点,比如客户临时提出一个美颜的需求。

    你评估了自己的 SDK 里面发现有人脸检测 API,有区域调色 API,有图像锐化 API,这个很轻易组装一个美颜的 API,所以你不需要从头开发出来。

    这就体现了开闭原则,开对于于需求,对需求的变动保持开发,闭对于已有的成果,不轻易破坏原有代码的稳定性。

    在这里插入图片描述

    3. 里氏替换原则(Liskov Substitution Principle)

    描述:所有引用基类的地方必须能透明地引用其子类。

    理解:举个简单的例子,假如一个会议的参会要求是,你必须是农民。那么,可以定义农民为基类。所以,只要是集成了农民的子类比如花农、果农、种植水稻的农民都可以参加这个会议。

    在这里插入图片描述

    4. 迪米特法则(Law of Demeter)

    描述:只和你的直接朋友对话,不和陌生人对话。

    理解:这一个原则很具人生哲学代表性。本质还是为了解耦,避免不必要的耦合,降低复杂度,并且提高安全性。我们熟悉的谍战片都是这个模式,卧底只和一个上线对话。

    在这里插入图片描述

    5. 接口隔离原则(Interface Segregation Principle)

    描述:客户端不应该依赖于它不需要的接口,不同的类之间的关系应该建立在最少的接口基础上。

    理解:这其实就是解耦合的的具体体现。举个生动的例子。

    我认为接口应该是一种承诺,或者是协议。

    甲方给乙方一系列接口,就算给了承诺。

    但甲方多变,乙方做好心理打算就好了,有些话听听就好了,提取最有用的信息,完成自己的任务,万一需求变动,再改也方便,如果一开始就整那些有的没的的东西,甲方再改动需求时,影响的范围会更大。

    另外有种情况是,甲方有好几个乙方,不同的乙方需要一起协同。

    这要求不同乙方之间约定好对话窗口,目的也是降低耦合度,保护自己尽可能少受需求变动之苦。

    6. 依赖倒置原则(Dependence Inversion Principle)

    描述:上层不应该依赖于底层,底层应该依赖于上层。抽象不应该依赖于细节,细节应该依赖于抽象。

    理解:听起来挺拗口的,其实也好理解。

    dip)

    我是一个人,我从广州去深圳,我说我依赖汽车、火车、自行车,这站在软件角度都不对的,因为我太依赖于细节了,这样面对不了未来的需求变化,所以应该有更好的解决方法。

    正确的应该是,我依赖于交通工具这个接口或者是抽象类。

    那么,我坐飞机、自行车、汽车、火车都满足情况,未来可能还有地铁、轻轨等等,这就是面向未来的编程方式。

    也是底层依赖上层,细节依赖抽象的意思。

    依赖倒置的意思是,本来 Person 依赖于具体的实现类,后来引进了交通工具这个抽象类,自行车、汽车、火车这些交通工具反而要依赖于接口,这个从被依赖到依赖别人的改变就看做是依赖关系的倒置,所以叫依赖倒置。

    最后,拥抱变化不是一句空话,你得反映到代码中来。

    展开全文
  • 作者:FeelsChaoticjuejin.im/post/5c57b2d5e51d457ffd56ffbb前言本文将从另一个角度讲解 AOP,从宏观实现原理和设计本质入手。大部分讲 AOP 博文都是一上来就罗列语法,然后敲个应用 demo就完了 。但学习不能知...

    点击上方“Java知音”,选择“置顶公众号”

    技术文章第一时间送达!

    作者FeelsChaotic

    juejin.im/post/5c57b2d5e51d457ffd56ffbb

    前言

    本文将从另一个角度讲解 AOP,从宏观的实现原理和设计本质入手。大部分讲 AOP 的博文都是一上来就罗列语法,然后敲个应用 demo就完了 。但学习不能知其然,不知其所以然。

    对 AOP 我提出了几点思考:

    • AspectJ 为什么会大热?

    • AspectJ 是怎样工作的?

    • 和 Spring AOP 有什么区别?

    • 什么场景下适用我们能不能自己实现一个 AOP 方法?

    一、引入

    敲一个小 Demo 来引入主题,假设我想不依赖任何 AOP 方法,在特定方法的执行前后加上日志打印。

    第一种方式:写死代码

    定义一个目标类接口

    74831fc2eb1679fff71d9253b18b77a9.png

    ce2e55bc45baf84b277496a1876acb92.png

    把 before() 和 after() 方法写死在 execute() 方法体中,非常不优雅,我们改进一下。

    第二种方式:静态代理

    3a49ca581f30c4754f68f0b115da9d48.png

    但是存在一个问题,随着打印日志的需求增多,Proxy 类越来越多,我们能不能保持只有一个代理呢?这时候我们就需要用到 JDK 动态代理了。

    第三种方式:动态代理

    新建动态代理类

    8e1cf1126e939b97a1e31eb2f5c07432.png

    客户端调用

    951d3c3a056d5a6cfd7c57a5dfd72a93.png

    这又引出一个问题,日志打印和业务逻辑耦合在一起,我们希望把前置和后置抽离出来,作为单独的增强类。

    第四种方式:动态代理 + 分离增强类

    新建增强类接口和实现类

    13b7b877a77b27bf446f5e2c217188fb.png

    用反射代替写死方法,解耦代理和操作者

    0b62b5b737e0ec4139282b237bcbd83f.png

    客户端调用

    8b80d5d711713054c9be8a542279ab2c.png

    但是用了反射性能太差了,而且动态代理用起来也不方便,有没有更好的办法?

    我们发现 Demo 存在种种问题

    • 静态代理每次都要自己新建个代理类,太繁琐,重用性又差,一个代理不能同时代理多种类;

    • 动态代理可以重用,但性能太差;

    • 代理类耦合进被代理类的调用阶段,万一我需要改下 before、after 的方法名,可能会点燃一个炸弹;

    • 代理拦截了一个类,就会拦截这个类的所有方法,难道我还要在代理类里加个 if-else 判断特定方法过滤拦截?我们可以不可以只拦截特定的方法?

    • 如果我既要打印日志,又要计算方法执行用时,每次都要去改增强类吗?

    我们的诉求很简单:1. 性能高;2. 松耦合;3. 步骤方便;4. 灵活性高。

    那主流的 AOP 框架是怎么解决这个问题的呢?我们赶紧来看看!

    二、AOP 方法

    不同的 AOP 方法原理略微有些不同,我们先看下 AOP 实现方式有哪些:

    208b323450ba598dfe00a35c2293d2f6.png

    所有 AOP 方法本质就是:拦截、代理、反射(动态情况下),实现原理可以看作是代理 / 装饰设计模式的泛化,为什么这么说?我们来详细分析一下。Java:由浅入深揭开 AOP 实现原理

    三、静态织入原理,以 AspectJ 为例

    静态织入原理就是静态代理,我们以 AspectJ 为例。

    1. AspectJ 设计思路

    前面说到 Demo 存在的种种问题,AspectJ 是怎么解决的呢?AspectJ 提供了两套强大的机制:

    (1)切面语法 | 解决业务和切面的耦合

    AspectJ 中的切面,就解决了这个问题。

    @Before("execution(* android.view.View.OnClickListener.onClick(..))")

    我们可以通过切面,将增强类与拦截匹配条件(切点)组合在一起,从而生成代理。这把是否要使用切面的决定权利还给了切面,我们在写切面时就可以决定哪些类的哪些方法会被代理,从而逻辑上不需要侵入业务代码。

    而普通的代理模式并没有做到切面与业务代码的解耦,虽然将切面的逻辑独立进了代理类,但是决定是否使用切面的权利仍然在业务代码中。这才导致了 Demo 中种种的麻烦。

    AspectJ 提供了两套对切面的描述方法:

    1.我们常用的基于 java 注解切面描述的方法,写起来十分方便,兼容 Java 语法;

    @Aspect
    public class AnnoAspect {
        @Pointcut("execution(...)")
        public void jointPoint() {
        }

        @Before("jointPoint()")
        public void before() {
            //...
        }

        @After("jointPoint()")
        public void after() {
            //...
        }
    }

    2.基于 aspect 文件的切面描述方法,这种语法不兼容 Java 语法。

    public aspect AnnoAspect {

        pointcut XX():execution(...);
        before(): XX() {
            //...
        }
        after(): XX() {
            //...
        }
    }    

    (2)织入工具 | 解决代理手动调用的繁琐

    那么切面语法让切面从逻辑上与业务代码解耦,但是我要怎么找到特定的业务代码织入切面呢?

    两种解决思路:一种就是提供注册机制,通过额外的配置文件指明哪些类受到切面的影响,不过这还是需要干涉对象创建的过程;另外一种解决思路就是在编译期或类加载期先扫描切面,并将切面代码通过某种形式插入到业务代码中。

    那 AspectJ 织入方式有两种:一种是 ajc 编译,可以在编译期将切面织入到业务代码中。另一种就是 aspectjweaver.jar 的 agent 代理,提供了一个 Java agent 用于在类加载期间织入切面。

    2. 通过 class 反推 AspectJ 实现机制

    (1)@Before 机制

    国际惯例写个 Demo

    1.自定义 AutoLog 注解

    04a756a12c85d5f21a655cc1ce64f5de.png

    2.编写 LogAspect 切面

    402a471fc1bcc96bfcf58e03e1d03809.png

    3.在切入点中加上注解

    03dde4f5d45fc265bc6b75b1bb989379.png

    反编译后(请点开大图查看)

    a29db7be2654bfc48e3e859c71a5c66f.png

    发现 AspectJ 会把调用切面的方法插入到切入点中,且封装了切入点所在的方法名、所在类、入参名、入参值、返回值等等信息,传递给切面,这样就建立了切面和业务代码的关联。

    我们跟进 LogAspect.aspectOf().aroundJoinPoint(localJoinPoint); 一探究竟。

    e778add93506fa3fbc79d9aeb4302dbe.png

    我们发现了什么?其实 Before 和 After 的插入就是在匹配到的 JoinPoint 调用前后插入 Advise 方法,以此来达到拦截目标 JoinPoint 的作用。如下图所示:

    23592a0b68acb5d335f30b7267c5db1f.png

    (2)@Around 机制

    1.自定义 SingleClick 注解

    9745d5a33bfbe54dc2569e36cbd93c3c.png

    2.编写 SingleClickAspect 切面

    12f97312a08552f5046f5f836e9c04f0.png

    3.业务方加上注解

    94b494becfdaea1f919d309ff13d4461.png

    打开编译后的 class 文件(请点开大图查看)

    bb99dc993f55b191dd7caceff85cc11d.png

    我们发现和 Before、After 织入不一样了!前者的织入只是在匹配的 JoinPoint 前后插入 Advise 方法,仅仅是插入。而 Around 拆分了业务代码和 Advise 方法,把业务代码迁移到新函数中,通过一个单独的闭包拆分来执行,相当于对目标 JoinPoint 进行了一个代理,所以 Around 情况下我们除了编写切面逻辑,还需要手动调用 joinPoint.proceed() 来调用闭包执行原方法。

    我们看下 proceed() 都做了些什么

    ff235dccf0213cc001d769fe3c392897.png

    那这个 arc 是什么?什么时候拿到的呢?

    bef3ac9db3e612c3a07d9d23c4277fb8.png

    继续回溯

    0e5dc6b1943b0045c811573ef79c9405.png

    在 AroundClosure 闭包中,会把运行时对象和当前连接点 joinPoint 对象传入,调用 linkClosureAndJoinPoint() 绑定两端,这样在 Around 中就可以通过 ProceedingJoinPoint.proceed() 调用 AroundClosure,进而调用到目标方法了。

    那么一图总结 Around 机制:

    a2fde8e256317b1722966d5b1fb9690b.png

    我们从 AspectJ 编译后的 class 文件可以明显看出执行的逻辑,proceed 方法就是回调执行被代理类中的方法。

    所以 AspectJ 做的事情如下:

    • 首先从文件列表里取出所有的文件名,读取文件,进行分析;

    • 扫描含有 aspect 的切面文件;

    • 根据切面中定义规则,拦截匹配的 JoinPoint ;

    • 继续读取切面定义的规则,根据 around 或 before ,采用不同策略织入切面。

    (3)@Before @After 机制与 @Around 机制区别

    • Before、After 仅仅是织入了 Advise 方法

    • Around 使用了代理 + 闭包的方式进行替换

    3. AspectJ 底层技术总结

    分析完 class 你会发现,AspectJ 实际上就是用一种特定语言编写切面,通过自己的语法编译工具 ajc 编译器来编译,生成一个新的代理类,该代理类增强了业务类。

    AspectJ 就是一个代码生成工具;

    编写一段通用的代码,然后根据 AspectJ 语法定义一套代码生成规则,AspectJ 就会帮你把这段代码插入到对应的位置去。Java知音扩展:代码神器:拒绝重复编码,这款IDEA插件了解一下.....

    AspectJ 语法就是用来定义代码生成规则的语法。

    扩展编译器,引入特定的语法来创建 Advise,从而在编译期间就织入了Advise 的代码。

    如果使用过 Java Compiler Compiler (JavaCC),你会发现两者的代码生成规则的理念惊人相似。JavaCC 允许你在语法定义规则文件中,加入你自己的 Java 代码,用来处理读入的各种语法元素。

    四、动态织入原理,以 Spring AOP 为例

    动态织入原理就是动态代理。

    1. Spring AOP 执行原理

    Spring AOP 利用截取的方式,对被代理类进行装饰,以取代原有对象行为的执行,不会生成新类。

    2. Spring AOP VS AspectJ

    可能有的小伙伴会困惑了,Spring AOP 使用了 AspectJ,怎么是动态代理呢?

    那是因为 Spring 只是使用了与 AspectJ 一样的注解,没有使用 AspectJ 的编译器,转向采用动态代理技术的实现原理来构建 Spring AOP 的内部机制(动态织入),这是与 AspectJ(静态织入)最根本的区别。

    Spring 底层的动态代理分为两种 JDK 动态代理和 CGLib:

    JDK 动态代理用于对接口的代理,动态产生一个实现指定接口的类,注意动态代理有个约束:目标对象一定是要有接口的,没有接口就不能实现动态代理,只能为接口创建动态代理实例,而不能对类创建动态代理。

    CGLIB 用于对类的代理,把被代理对象类的 class 文件加载进来,修改其字节码生成一个继承了被代理类的子类。使用 cglib 就是为了弥补动态代理的不足。

    3. JDK 动态代理的原理

    我们前面的 Demo 第三种方式使用了动态代理,我们不禁有了疑问,动态代理类及其对象实例是如何生成的?调用动态代理对象方法为什么可以调用到目标对象方法?

    e62bcbf854528f3df13bc642b1eb077e.png

    我们通过 Proxy.newProxyInstance 可以动态生成指定接口的代理类的实例。我们来看下newProxyInstance内部实现机制。

    fb9c902155a28c6cd81b78828caa93be.png

    代理对象会实现接口的所有方法,实现的方法交由我们自定义的 handler 来处理。

    56d2a7c5a207699d031198bdf5d1e75b.png

    我们看下 getProxyClass0 方法,只凭一个类加载器、一个接口,是怎么创建代理类的?

    d2a61ca90671ecdf386a92dcb9476a5e.png

    注意一下:Android 中动态代理类是直接生成,而 Java 是生成代理类的字节码,再根据字节码生成代理类。

    那么客户端就可以 getProxy() 拿到生成的代理类 com.sun.proxy.$Proxy0

    2c2580a175139fb156c3d64080baa674.png

    这个代理类继承自 Proxy 并实现了我们被代理类的所有接口,在各个接口方法的内部,通过反射调用了 InvocationHandlerImpl 的 invoke 方法。

    总结下步骤:

    • 获得被代理类的接口信息,生成一个实现了代理接口的动态代理类;

    • 通过反射获得代理类的构造函数;

    • 利用构造函数生成动态代理类的实例对象,在调用具体方法前调用 invokeHandler 方法来处理。

    36adfc7e6e06027e77f3b619ec564acb.png

    后记

    1. 设计模式不能脱离业务场景

    不知不觉我们复习了一下代理模式,设计模式必须依赖大量的业务场景,脱离业务去看设计模式是没有意义的。

    因为脱离了应用场景,即使理解了模式的内容和结构,也学不会在合适的时候应用。

    设计模式推荐:设计模式内容聚合

    2. 敢于追求优雅的代码

    首先你要敢于追求优雅的代码,就像我们开头的打印日志的需求,不断提出问题,不断追求更好的解决方案,在新的方案上挖掘新的问题……如果你完全不追求设计,那自然是不会想到去研究设计模式的。

    END

    Java面试题专栏

    【41期】盘点那些必问的数据结构算法题之链表【42期】盘点那些必问的数据结构算法题之二叉堆【43期】盘点那些必问的数据结构算法题之二叉树基础【44期】盘点那些必问的数据结构算法题之二分查找算法【45期】盘点那些必问的数据结构算法题之基础排序【46期】盘点那些必问的数据结构算法题之快速排序【47期】六大类二叉树面试题汇总解答【48期】盘点Netty面试常问考点:什么是 Netty 的零拷贝?【49期】面试官:SpringMVC的控制器是单例的吗?【50期】基础考察:ClassNotFoundException 和 NoClassDefFoundError 有什么区别

    7485db5a60498fcd3c767ed68dfd2c63.png

    我知道你 “在看72db43c5c75d995b86bd34d40137eff9.gif

    展开全文
  • 关于状态观测器本质的理解

    千次阅读 2020-06-17 11:39:47
    前面我们提到过,观测器有很多种,其中一种就是状态观测器,系统某一状态进行观测。 但是在实际中我们会遇到一种情况:就是我们获取某一状态就是系统输出,即y=x,那为什么此时我们还要设计观测器呢,直接 ...

    前面我们提到过,观测器有很多种,其中一种就是状态观测器,对系统的某一状态进行观测。

    但是在实际中我们会遇到一种情况:就是我们获取的某一状态就是系统的输出,即y=x,那为什么此时我们还要设计观测器呢,直接将获取的输出作为状态值不行吗?于是这就体现了状态观测器的本质——滤波。

    我们经常接触的卡尔曼滤波器就是一种状态观测器,他对状态值进行滤波估计。

    而模型的输出往往带有噪声和干扰,所以直接将输出作为状态值是不妥的,因此设计状态观测器就是为了获取到更好的状态值,过滤掉噪声。我们之前学习的扩张状态观测器则更加高级,它不仅能够过滤噪声对状态值和状态值的微分进行过滤估计,还可以对干扰进行估计!!!!!

    展开全文
  • 首先不得不说《深入理解计算机系统》着是一本很不错书,有一种强烈推荐给咱们计算机科学学院同学把它作为程序设计及计算机科学入门书籍冲动,当然,话说我也只是一个学生角色,还是要“在其位,谋其政”啊...

            首先不得不说《深入理解计算机系统》着的是一本很不错的书,有一种强烈推荐给咱们计算机科学学院的同学把它作为程序设计及计算机科学入门书籍的冲动,当然,话说我也只是一个学生的角色,还是要“在其位,谋其政”啊。但是强烈推荐每个学习计算机专业的同学看下这本书的愿望还是有的。就像一条书评说的“计算机专业的同学越早接触这本书越好”,自认为这本书是迄今为止对我影响最深的一本书,是我对计算机系统不只是编程有了一个全面深入的理解,看到了计算机的本质。现在觉得学东西还是要看清本质再学,否则知识学习表面东西就像是只学招式而不练内功一样,不会有真正地提高的。

            从这学期开始一段时间后就突发奇想,相对程序和计算机有更深入的了解,不想只是停留在会写代码,会调用别人程序的基础上,对写好代码后编译器、CPU、操作系统做的事很好奇,很想去知道他们是怎么样运行一个程序的,怎么样把一个个字母,数字,值,语句,函数,类,组织到一起,然后运行出我们行要的结果的。类似于这样的问题让我不安,因为有问题却没有学习过相关的内容,感觉无从下手。我想如果我们学习过《编译原理》这本科应该不会这么迷惑了吧。于是开始在网上大量下载资料(CSDN上用免积分下载器狂下),只要是有关程序的设计底层点的就下载(包括硬盘结构,因为当时对硬盘上如何存数据也很着迷),包括计算机构造,计算机组成,冯诺依曼结构等等的相关资料:                                                                                                

              这期间淘到两本好书(自认为):《操作系统:精髓与设计原理中文第六版》和深入理解计算机系统(原书第2.)》。尤其是第二本,至于第一本我是这样想的:引用别人的理解“操作系统就是覆盖在计算机硬件上的一层软件”,计算机由硬件和软件组成,而操作系统是最大的软件,所以我认为掌握好,学好操作系统就可以最大程度的直接操作硬件了,所以想深入了解下OS。但是开始读读二本(《深入理解计算机系统(原书第2.)》时,才发现这本书才是我寻寻觅觅已久的“圣经”。于是爱不释手,每天早上开始巴在演示器上认真的拜读……终于忍不住了,PDF的版本看的眼睛疼,在京东上搜索了一下,有这本书就果断买下来了(之前去图书馆借过,但是此书不知道被那位同仁借去拜读忘了归还了……)。

             花了了几个星期,大概略读了一遍(个别难点第一次读时放过,第四六章节放过,因为考虑到要找实习了时间紧张……),感觉心中的一些疑惑解决了一半。但还是不够透彻,又过了两星期,决定再读一遍,不然干什么呢?学计算机的连计算机系统都没有理解学别的不都是学点乱七八糟的招式嘛,还自欺欺人(纯属个人观点)。于是又开始拉克第二编的阅读与理解。到现在已经读完第一部分和第二部分(第一张至第九章),第三部分(第十章)刚开始。

           书读到此书,已经颇有几分像写点东西和大家分享交流的感觉了,

           之前百度过几次“编程的本质”,有几篇文章写得不错,还有一本STL之父写的《编程原本》(汉语版),观点不尽相同,但都有一些共同点。《编程原本》一直阐述的是:数学对于编程视觉好的东西,理论对于实际是绝好的东西。其他文章强调的是把一个实际问题转换为一个程序的思想的重要性。

           通过自己之前一些调试(VC6下看汇编语言,很多movmov那的)的体验和读书的理解,程序就是在倒腾数据,折腾寄存器,从一个寄存器到另一个寄存器,从一个寄存器到另一个存储器,比如:把数据从内存倒腾到显卡就能显示各种画面文字了,把数据从客户电脑的内存上倒腾到网卡上,再从网卡上倒腾到服务器的网卡上,再从服务器网卡上倒腾到服务器内存上就能实现Web服务了。其他的图像,文字,音频,视频等的,都是先把他们转化成数字,然后倒腾来倒腾去的就成了各种图像处理,文字处理,音、视频处理软件了。但是了解了本质也能说就完全掌握了,因为关键就在于怎么倒腾上,就像你可以说人的本质就是“吃喝拉撒”,但是你能说人的作用就只有这些吗?

          就像《道德经》里说的,宇宙的本源是“无”,但是天地创造了万物,就是“有”。本质是“无”而“有”发挥了作用。

          一个完整的应用或者程序就像是这样的过程:

     

    另一种理解:

         也有人说:“个人以为,从编程这一职业诞生开始一直至今,其本质就没有改变过。对概念的抽象对逻辑的描述始终都是编程过程中最核心的东西。”(引自http://topic.csdn.net/u/20120601/11/0639e82e-6183-4b7f-9ab1-090dd92ac13d.html?r=78767350 )。以及“程序设计的实质就是编制计算机加工数据的步骤!”的理解(引自http://bbs.chinaunix.net/thread-1029967-2-1.html )

             但为什么说理解本质了不能说是完全展购物了呢?因为“谁不知道程序是调用这个函数那个方法?问题是,你知道XX情况下可以调用哪个、适合调用哪个吗?你只有所谓的基础,你不知道。你可能将某个程序的流程图画得相当准确,处理过程说得头头是道,但你能写出具体的代码,正确编译出你描述的程序吗?你不能。”“让你参与某个项目,你一看,这工具不会,那函数没见过,你又看不上这些东西,那企业要你何用?企业又不是福利院。”(引自百度知道:http://zhidao.baidu.com/question/335060475.html可以理解为:“本质”发挥“作用”,本质永恒不变,但是作用却是千变万化的。所以,理解了程序本质只是说你也已在一个正确的指导思想下学习了,而且是学习更多的知识,我觉得学无止境永远是不断进步的途径,没有什么捷径,掌握的越多,你会的技术(包括编程语言)越多,你解决问题的方法就越多,引用一句经典“如果你手里只有锤子,那你看的所有问题都是钉子”。
                   现在回头一想,了结了程序的本质,问题就来了:这倒腾来倒腾去干啥呀!??到底应该学点什么呢??
    开复老师的这篇文章有很好的建议:
    http://blog.csdn.net/l109383670/article/details/5273340
    http://wenku.baidu.com/view/4fdf60956bec0975f465e29b.html
     
    另还有一篇CSDN上的文章也不错:

    http://blog.csdn.net/ex_net/article/details/7583396大学生如何让自己强大起来(计算机、电子方向)

    (其实可以看出,大部分强调的事软实力,对基础的熟练掌握,对实践的体会,对细节的执着还有对计算机的深入理解)
    其他相关文章推荐:
    编程本质相关:
    http://wenku.baidu.com/view/74e4d9482e3f5727a5e962d2.html
    http://blog.csdn.net/a379039233/article/details/6929772
    http://www.cnblogs.com/pm_2004/archive/2004/08/02/28654.html
    http://topic.csdn.net/u/20110326/21/fa8e80ff-16a8-42af-9db9-d511cbc974a0.html
    http://topic.csdn.net/u/20120601/11/0639e82e-6183-4b7f-9ab1-090dd92ac13d.html
    http://www.aqee.net/the-singular-secret-of-the-rockstar-programmer/
     
    关于计算机专业如何学习相关:
    http://blog.csdn.net/fenghaibo00/article/details/6706869
    http://hi.baidu.com/shfr1101/item/6336370ed7e4378802ce1b86
    http://hi.baidu.com/%CF%E2%D3%D0%BD%F0%B1%DF%B5%C4%D4%C6/blog/item/6fde81a940ed2cb9cb130c9e.html

    http://news.cnblogs.com/n/91108/                   给想当程序员的大二学生的建议

    http://www.aqee.net/advice-from-an-old-programmer/              《一个老程序员的建议》http://blog.csdn.net/bing63983627/article/details/6595002              IT学生解惑真经》

     
    希望对大家得学习起到一定的帮助作用,也就是实现这些文字的一点价值了。
    展开全文
  • 抽象过程也是一个裁剪过程,不同、非本质特征全部裁剪掉了,即就是抽取事物共同特征就是抽取事物的本质特征,舍弃不同特征。 面向对象软件开发起点就是抽象建模过程,即就是识别参与问题领域实体,...
  • 一、创造型模式 1. 工厂模式: 此模式主要就是将现实生活中场景拉进来。现实生活中,假设你要买一台台式机,你可以有两种选择:要么所有组件都自己买,买回来之后自己再组装成...这个模式实际上就是把工厂生产
  • 设计模式的本质在于抽象,用抽象隔离变化,用抽象分解复杂事物为一个个单一职责个体.... 思路是很直观,对设计模式误用往往在于,过度分解造成组装结构上复杂性和难以理解. 所以要在分解和组装上达到一个平衡.
  • 面向对象程序设计,我记得好像是上世纪70年代提出来,具体时间不太记得了,那么到现在...其实,我个人觉得,不管是面向对象,还是结构化程序设计,从流程和逻辑来看,其本质都是一样,不一样是分析和实现
  • 设计模式通俗理解

    2013-04-27 17:37:00
    最近一直在看设计模式方面的书,各种设计模式也看了不少,不过编程的这种思想,不是看书就能看好的,还是要多在实践中去总结,一般面试的时候,面试官比较喜欢问对设计模式的理解,我觉得吧,从总体上来说,设计模式...
  • 最近读了一篇非常不错的文章《我技术架构的理解与架构师角色思考》。 非常推荐大家也读读。 下面简单记录下此文的一些感想。 二、读后感 2.1 概况 1 文中【架构师角色】这一块讲得非常透彻。 架构师需要大量的...
  • Hibernate的理解

    2013-10-21 22:36:20
    Hibernate的理解  1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上...
  • hibernate的理解

    2018-04-18 22:44:39
    1.面向对象设计的软件内部运行过程可以理解成是在不断创建各种新对象、建立对象之间关系,调用对象方法来改变各个对象状态和对象消亡过程,不管程序运行过程和操作怎么样,本质上都是要得到一个结果,程序...
  • 2.在某一学科中,如果某个问题看起来是真实的且与学生相关,可以帮助学生所学知识达到更系统更深入的理解,可以让学生投入其中,那么我们就说这问题找了。3.基本问题是那些鼓励启发甚至要求我们超越特定主...
  • 从这一章开始,基本就脱离了结构化编程的思维,...感觉这一章的干货特别多,可以让我的面向对象思维上一个小小的台阶,这里将自己的学习笔记以及自己的理解整理分享出来,希望大家都有所帮助,还有一点要说明下...
  •  一直epoll的本质有一定的理解,但是又不够深入,被别人问起时,总是有一些悬而未决的问题答不出来。最后发现了这篇文章,我觉得真的特别棒。转载以学习之!  转载来源: https://bbs.gameres.
  • Handler的理解

    2019-09-30 17:30:25
    整个Android Framework都是基于...Handler 的本质是事件驱动程序设计模型在Android系统中具体实现,那事件驱动程序设计模型是什么? 事件驱动模型典型应用是GUI系统中,在GUI系统中应用程序要在未来不确定...
  • 异常简单理解

    2018-09-21 10:56:24
    一、异常的本质理解 java异常也属于一个jav对象(继承Object),它封装了一些成员变量和操作。异常就是一种错误情况,是程序不希望出现现象,但是由于程序本身的设计思路和运行环境等因素,出现异常情况是...
  • 混乱或错误的命名不仅让我们代码难以理解,更糟糕的是,会误导我们的思维,导致代码的理解完全错误。相反,良好的命名,则可以让我们的代码非常容易读懂,也能向读者正确表达事物以及逻辑的本质,从而使得代码的...
  • 在lab中很多时候都会要求使用一些模式来设计ADT,常用一些模式包括工厂模式、装饰器模式、单例模式、策略模式等等,今天在这里这些模式做个简单总结,介绍一些模式思想 工厂模式 工厂的本质是建立一个类以...
  • 在 Java 语言中, abstract class 和 interface 是支持抽象类定义的两种机制。...其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出 于问题领域本质的理解、对于设计意图的理解是否正确、合理。本文将
  • 架构的本质

    2017-04-11 10:52:04
    分享人:卫向军(毕业于北京...在开始谈我架构本质的理解之前,先谈谈今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,这个数量级我们战略上 要重 视 它 , 战术上又 要 藐 视 它。先举个例
  • 自身接口的理解 接口最本质的一点,具体的实现做一个限制。 例:一家地主,家里有一个老管家,地主有一套针对管家的规矩,老管家负责把这套规矩做好,至于怎么做好上面并不关系。这个时候老管家由于年纪过大,...
  • 谈谈hibernate的理解

    2014-02-13 19:13:52
    1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间关系,调用对象方法来改变各个对象状态和对象消亡过程,不管程序运行过程和操作怎么样,本质上都是要得到一个结果,...
  • 2006 年, 美国卡内基梅隆大学的周以真教授提出了计算思维的...本文采用了英国南安普敦大学的 Cyn- thiaSelby博士和 JohnWoollard博士计算思维的理解,将计算思维划分为分解思维、抽 象思维、算法思维、评估思维...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,253
精华内容 501
关键字:

对设计本质的理解