对充血模型的疑问

小弟我在坛子上看到关于贫血模型和充血模型的讨论后一直再想这对于我这种代码小工意味着啥?
是否可以更快更迅速更敏捷的完成代码完成开发。
一直做的项目都是SSH 然后分层 action,service,dao,entity;有时候我觉得dao层没什么必要啊,既然
hibernate是面向对象为何还要 dao.save(entity)   dao.update(entity) 这样操作?
感觉如果去掉dao层 直接entity.update(),entity.delete();  这样是否会更形象?
然后小弟开始尝试,首先搭了个struts2+spring3+Hibernate3.6的ssh工程用的是全注解搭法这样开发就不用写配置文件了还是相当的爽啊

首先我觉得应该有一个公共的类充当所有entity的父类


import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

import javax.annotation.Resource;

import org.hibernate.SessionFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository("MagicH")
public class MagicH extends HibernateTemplate {

@Resource(name = "sessionFactory")
public void setSuperSessionFactory(SessionFactory sessionFactory) {
    super.setSessionFactory(sessionFactory);
}

private Serializable id; // 标示
private Class clazz; // 实体
private Object entity; // 数据库实体
private PropertyDescriptor targetPds[];  //初始化后属性
private HashMap setMethodMap = new HashMap();   //set方法映射
private HashMap getMethodMap = new HashMap();  //get方法映射

/**
 * 模型初始化
 * 
 * @param clazz
 * @param id
 */
public boolean init(Class clazz, Serializable id) {
    this.id = id;
    this.clazz = clazz;
    PropertyDescriptor targetPds[] = BeanUtils.getPropertyDescriptors(clazz); 
      for (PropertyDescriptor pdObj : targetPds)
        {
           setMethodMap.put(pdObj.getName().toLowerCase(), pdObj.getWriteMethod());
           getMethodMap.put(pdObj.getName().toLowerCase(), pdObj.getReadMethod());
        }
      this.entity = get(clazz, id);
    return this.entity==null?false:true;  
}

/**
 * 获取对象实体
 * 
 * @return
 */
public Object getObj() {
    if (entity == null) {
        this.entity = get(clazz, id);
    }
    return entity;
}

/**
 * 删除对象实体
 */
public void delObj() {
    if (entity != null)
        delete(entity);
    else
        delete(get(clazz, id));
}

/**
 * 设置数据库实体属性
 * @param propertyName
 * @param propertyValue
 */
public void setProperty(String propertyName, Object propertyValue) {

      Method writeMethod = (Method) setMethodMap.get(propertyName.toLowerCase());
      try {
        writeMethod.invoke(entity, new Object[] {propertyValue});
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

/**
 * 获取属性的值
 * @param propertyName
 * @return
 */
public Object getPropertyValue(String propertyName)
{
    Method readMethod = (Method)getMethodMap.get(propertyName.toLowerCase());
    Object returnValue = null;
    try {
        returnValue = readMethod.invoke(entity,null);
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return returnValue;
}
/**
 * 更新对象
 */
public void updateObj()
{
    update(entity);
}


/**
 * 保存对象
 * @param obj
 * @return
 */
public Serializable addObj(Object obj)
{
    Serializable id =  save(obj);
    init(obj.getClass(),id);
    return  id;
}

}



建立一张用户表测试,对应实体如下

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.stereotype.Repository;

import com.usoft.core.dao.impl.MagicH;

/**

  • MagicUser entity. @author MyEclipse Persistence Tools
    */
    @Repository("MagicUser")
    @Entity
    @Table(name = "MAGIC_USER")
    public class MagicUser extends MagicH implements java.io.Serializable {

    // Fields

    private String userId;
    private String userNam;
    private String userSex;
    private String userPhone;

    // Constructors

    /** default constructor */
    public MagicUser() {
    }

    /** full constructor */
    public MagicUser(String userNam, String userSex, String userPhone) {
    this.userNam = userNam;
    this.userSex = userSex;
    this.userPhone = userPhone;
    }

    // Property accessors
    @GenericGenerator(name = "generator", strategy = "uuid.hex")
    @Id
    @GeneratedValue(generator = "generator")
    @Column(name = "USER_ID", unique = true, nullable = false, length = 32)
    public String getUserId() {
    return this.userId;
    }

    public void setUserId(String userId) {
    this.userId = userId;
    }

    @Column(name = "USER_NAM", length = 500)
    public String getUserNam() {
    return this.userNam;
    }

    public void setUserNam(String userNam) {
    this.userNam = userNam;
    }

    @Column(name = "USER_SEX", length = 1)
    public String getUserSex() {
    return this.userSex;
    }

    public void setUserSex(String userSex) {
    this.userSex = userSex;
    }

    @Column(name = "USER_PHONE", length = 11)
    public String getUserPhone() {
    return this.userPhone;
    }

    public void setUserPhone(String userPhone) {
    this.userPhone = userPhone;
    }

}


这是本人测试用的service


import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.usoft.magich.bs.ImagicServiceTest;
import com.usoft.magich.vo.MagicUser;

@Service("MagicService")
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public class MagicServiceTestImpl implements ImagicServiceTest {

@Resource
private MagicUser magicUser;

public void testMagicH() {
    //保存
    magicUser.setUserNam("用户123");
    magicUser.setUserPhone("12345");
    magicUser.setUserSex("1");
    magicUser.addObj(magicUser);

   //更新
    magicUser.setProperty("UserNam", "1234567");
    magicUser.updateObj();

    System.out.print(magicUser.getPropertyValue("UserNam"));

    boolean b1 = magicUser.init(magicUser.getClass(), "aaa");  //id 不存在初始化失败
    System.out.println(b1);

    boolean b2 = magicUser.init(magicUser.getClass(),"402881862da6ec3b012da6fb4f640004"); //id存在为 true
    System.out.println(b2);
    magicUser.delObj(); //删除 对象
}

}



只是中午吃饭时脑子那么想了一下,然后回来就尝试写了个单表的增删改查,我个人举得无论是单表还是多表最后数据库查出来的无非是个二叉表,而其中的一条记录应该对应一个java类 多条记录则是该java类的List集合,然后所有的数据库操作不再是dao.doSomething 而是entity.doSomething
我这样做了后写的代码就只有actiong,service,entity层了,不知道这样是否可行,谁能解释一下我的疑问。


问题补充
看了大家的回复深受启发,感觉自己这个想法似乎不可取就不再钻牛角尖了。
可能一直处于开发人员的角色,所以关系的核心问题无非就是 写最少的代码做最多的事

21个回答

一个问题的作用域将决定一个问题的解决方案是否合适。其实这也是大多数人对于领域模型各种变种的误解。

当一个简单类具备了field和method之后,大师们告诉你,这个类的实例叫做对象,基于这种方式写出来的程序叫OO。大师们还告诉你,只有field和它们对应的setter/getter方法的类,不怎么OO,因为这叫贫血。在类上加上method,赋予类逻辑执行能力,这叫领域模型,比较OO。

恩,我们不妨考虑一个拥有3000w行代码的大系统,假设它需要1000个领域模型类。这相当于把一个最简单的问题放大了1000倍,那么我们等于把我们的逻辑重复1000遍。当然,这个系统的逻辑不再是增删改查那么简单,而是有复杂的业务流程。这个时候,你会发现,一个领域模型类可能将达到20K,甚至30K那么大。里面可能有超过40个method,对应30种不同的业务流程。

某天,项目经理说,hey,小伙子,客户说这业务改了,它们要在所有涉及到数据库保存的地方加条日志,并通知另外一个系统。想象一下你的工作?在一个超过2000行的类里面,找到那些方法,一个个加过来。恩,这就是专家们说的,这很OO。

哈哈,你这个Entity充血的解释比较有意思。你这种做法,我们几年前的时候就这样做了,你那个Entity类只不过是个Dao的基类,提供了通用的增删改查改功。这并不是什么充血模型,至多算伪充血,还容易误导人概念。我觉得Entity名字换成BaseDao名比较好。充血模型更多应该从领域对象出发。

你这个MagicUser类无法作为模型,因为他无法通过new的方式创建。

你的做法,说白了就是把model层和dao层合并了,没有带来任何别的变化,这种做法不会让你的开发变得更快。

此外还引入了以下问题:
1.你的领域对象和Hibernate框架完全耦合
2.领域对象承担了不属于它的职责,即持久化。好吧,或许你会说“持久化”也可以算它的职责,那么至少“写入数据库”不是它的职责,为了剥离这个职责,演化之后你还是需要一个DAO层。
3.从第2个问题就衍生出第3个问题,你知道有些领域对象是不需要持久化的,只在内存中,但按照你这个框架来的话,随随便便就要抛exception

holdmydream
holdmydream 精辟,精华
7 年多之前 回复

我不如用一个基于反射的基础数据库操作的BASEDAO

在SERVICE层里 我自动注入这个基操作DAO,如:

@Resource
BASEdao userDao;

个人偏向于贫血,但是特殊业务下,如文章的图片在创建时建创UUID文件名的文件夹,删除时自动删除,== 我会在POJO中注血的

ObjectWeb的DODS就如你想象的“充血模型”,以前改shark源码的时候接触过这个持久层框架一段时间,但不得不说,比起实体与DAO分离的“贫血模型”来说,实在是很不好用。

充血模型,领域驱动个人觉得最好的解决之道在于DOMAIN EVENT 的应用

为什么Rod不把HibernateTemplate定义为final类型的!

用SSH做一个应用是多么麻烦啊,要写这么多代码,长此下去,必成代码工人

共21条数据 1 3 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
什么是贫血模型,失血模型,充血模型
小弟分不清楚这几个模型了,麻烦给个答案或者给个好点的文章。先谢谢啦。最好有对照的代码 :idea: 谢谢!
Android这样的JSON数据应该怎么解析。
![图片说明](https://img-ask.csdn.net/upload/201602/22/1456108401_398697.jpg) 这是一个选择添加疾病的页面。 第一行是疾病类型 第二行是疾病名称 要求上面的疾病类型和疾病名称都要从服务器获取。 每种疾病类型下面的疾病名称数量不确定 还有可以点击选择添加日期,不过这个问题我已经解决了。 我采用的是ListView展示的。但是解析过后有问题,只能解析到疾病类型,解析不到疾病名称。 每个疾病类型和疾病名称都有ID。 这是用网页访问JSP网址的返回值。 {"code":200,"message":"调用成功","data":{"mem_message_records":[{"message_disease_typeid":"1","message_disease_type":"心血管系统"},{"message_disease_typeid":"2","message_disease_type":"外围血管疾病"},{"message_disease_typeid":"3","message_disease_type":"脑血管疾病"},{"message_disease_typeid":"4","message_disease_type":"肺部疾病"},{"message_disease_typeid":"5","message_disease_type":"代谢疾病"},{"message_disease_typeid":"6","message_disease_type":"周围神经疾病"},{"message_disease_typeid":"7","message_disease_type":"其他疾病"}],"mem_message_recordss":[[{"message_diseaseid":"1","message_disease":"冠状动脉疾病"},{"message_diseaseid":"2","message_disease":"心绞痛"},{"message_diseaseid":"3","message_disease":"心肌梗死"},{"message_diseaseid":"4","message_disease":"冠状动脉血运重建"},{"message_diseaseid":"5","message_disease":"充血性心力衰竭"}],[{"message_diseaseid":"6","message_disease":"闭塞性周围动脉粥样硬化"},{"message_diseaseid":"7","message_disease":"血栓行静脉炎"}],[{"message_diseaseid":"8","message_disease":"脑血栓"},{"message_diseaseid":"9","message_disease":"短暂性脑供血不足"},{"message_diseaseid":"10","message_disease":"脑出血"}],[{"message_diseaseid":"11","message_disease":"慢性支气管炎"},{"message_diseaseid":"12","message_disease":"慢性阻塞性肺病"},{"message_diseaseid":"13","message_disease":"支气管哮喘"},{"message_diseaseid":"14","message_disease":"间质性肺病"},{"message_diseaseid":"15","message_disease":"囊性肺纤维化"}],[{"message_diseaseid":"16","message_disease":"1型糖尿病"},{"message_diseaseid":"17","message_disease":"2型糖尿病"},{"message_diseaseid":"18","message_disease":"糖尿病肾病"}],[{"message_diseaseid":"19","message_disease":"糖尿病性周围精神病"},{"message_diseaseid":"20","message_disease":"自主神经性病变"}],[{"message_diseaseid":"21","message_disease":"高血压"},{"message_diseaseid":"22","message_disease":"视网膜病变"},{"message_diseaseid":"23","message_disease":"恶性肿瘤"},{"message_diseaseid":"24","message_disease":"脑卒中"},{"message_diseaseid":"25","message_disease":"重性精神疾病"},{"message_diseaseid":"26","message_disease":"结核病"},{"message_diseaseid":"27","message_disease":"肝炎"},{"message_diseaseid":"28","message_disease":"先天畸形"},{"message_diseaseid":"29","message_disease":"其它"}]]}}
Android解析JSON数组,如果里面有两个数组,要怎么处理
项目中遇到服务器给的文档里面有两个数组 这样 { "code":200, "message":"调用成功", "data":{ "mem_message_records":[ { "message_disease_typeid":"1", "message_disease_type":"心血管系统" }, { "message_disease_typeid":"2", "message_disease_type":"外围血管疾病" }, { "message_disease_typeid":"3", "message_disease_type":"脑血管疾病" }, { "message_disease_typeid":"4", "message_disease_type":"肺部疾病" }, { "message_disease_typeid":"5", "message_disease_type":"代谢疾病" }, { "message_disease_typeid":"6", "message_disease_type":"周围神经疾病" }, { "message_disease_typeid":"7", "message_disease_type":"其他疾病" } ], "mem_message_recordss":[ [ { "message_diseaseid":"1", "message_disease":"冠状动脉疾病" }, { "message_diseaseid":"2", "message_disease":"心绞痛" }, { "message_diseaseid":"3", "message_disease":"心肌梗死" }, { "message_diseaseid":"4", "message_disease":"冠状动脉血运重建" }, { "message_diseaseid":"5", "message_disease":"充血性心力衰竭" } ], [ { "message_diseaseid":"6", "message_disease":"闭塞性周围动脉粥样硬化" }, { "message_diseaseid":"7", "message_disease":"血栓行静脉炎" } ], [ { "message_diseaseid":"8", "message_disease":"脑血栓" }, { "message_diseaseid":"9", "message_disease":"短暂性脑供血不足" }, { "message_diseaseid":"10", "message_disease":"脑出血" } ], [ { "message_diseaseid":"11", "message_disease":"慢性支气管炎" }, { "message_diseaseid":"12", "message_disease":"慢性阻塞性肺病" }, { "message_diseaseid":"13", "message_disease":"支气管哮喘" }, { "message_diseaseid":"14", "message_disease":"间质性肺病" }, { "message_diseaseid":"15", "message_disease":"囊性肺纤维化" } ], [ { "message_diseaseid":"16", "message_disease":"1型糖尿病" }, { "message_diseaseid":"17", "message_disease":"2型糖尿病" }, { "message_diseaseid":"18", "message_disease":"糖尿病肾病" } ], [ { "message_diseaseid":"19", "message_disease":"糖尿病性周围精神病" }, { "message_diseaseid":"20", "message_disease":"自主神经性病变" } ], [ { "message_diseaseid":"21", "message_disease":"高血压" }, { "message_diseaseid":"22", "message_disease":"视网膜病变" }, { "message_diseaseid":"23", "message_disease":"恶性肿瘤" }, { "message_diseaseid":"24", "message_disease":"脑卒中" }, { "message_diseaseid":"25", "message_disease":"重性精神疾病" }, { "message_diseaseid":"26", "message_disease":"结核病" }, { "message_diseaseid":"27", "message_disease":"肝炎" }, { "message_diseaseid":"28", "message_disease":"先天畸形" }, { "message_diseaseid":"29", "message_disease":"其它" } ] ] } } 下面是我构建的实体类 这是最里层的两个, //疾病名称 public class JiBingdataname { private String message_diseaseid; private String message_disease; } //疾病类型 public class JiBingdata { private String message_disease_type; private String message_disease_typeid; } //外一层 public class JiBinglist { private List<JiBingdata> mem_message_records; private List<JiBingdataname> mem_message_recordss; } //最外层 public class JiBingbean { private String code; private String message; private JiBinglist data; } 下面是我的解析代码 //解析JSON数据 private class Mythread extends Thread { @Override public void run() { System.out.println("....启动线程"); //网络请求路径 String path = HttpInfo.PATH + HttpInfo.GET_JIBINGLIST + HttpInfo.ID; String jsonString = HttpUtils.getJsonContent(path); Gson gson = new Gson(); System.out.println("------------------------" + path); //解析json数据 jiBingbean = gson.fromJson(jsonString, JiBingbean.class); System.out.println("....启动线程" + jiBingbean); //解析成功后发送msg给UI主线程 Message msg = new Message(); msg.what = 101; myHandler.sendMessage(msg); } } 但是出现这样的问题 java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 520 path $.data.mem_message_recordss[0] logcat日志错误指向这一行, jiBingbean = gson.fromJson(jsonString, JiBingbean.class); 请教一下各位大神,是哪里处理的不好
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 free -m 其中:m表示兆,也可以用g,注意都要小写 Men:表示物理内存统计 total:表示物理内存总数(total=used+free) use...
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发...
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 演示地点演示 html代码如下` music 这个年纪 七月的风 音乐 ` 然后就是css`*{ margin: 0; padding: 0; text-decoration: none; list-...
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。
数据库优化 - SQL优化
以实际SQL入手,带你一步一步走上SQL优化之路!
通俗易懂地给女朋友讲:线程池的内部原理
餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
使用 Docker 部署 Spring Boot 项目
Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下。首先构建一个简单的 S...
英特尔不为人知的 B 面
从 PC 时代至今,众人只知在 CPU、GPU、XPU、制程、工艺等战场中,英特尔在与同行硬件芯片制造商们的竞争中杀出重围,且在不断的成长进化中,成为全球知名的半导体公司。殊不知,在「刚硬」的背后,英特尔「柔性」的软件早已经做到了全方位的支持与支撑,并持续发挥独特的生态价值,推动产业合作共赢。 而对于这一不知人知的 B 面,很多人将其称之为英特尔隐形的翅膀,虽低调,但是影响力却不容小觑。 那么,在...
面试官:你连RESTful都不知道我怎么敢要你?
干货,2019 RESTful最贱实践
刷了几千道算法题,这些我私藏的刷题网站都在这里了!
遥想当年,机缘巧合入了 ACM 的坑,周边巨擘林立,从此过上了"天天被虐似死狗"的生活… 然而我是谁,我可是死狗中的战斗鸡,智力不够那刷题来凑,开始了夜以继日哼哧哼哧刷题的日子,从此"读题与提交齐飞, AC 与 WA 一色 ",我惊喜的发现被题虐既刺激又有快感,那一刻我泪流满面。这么好的事儿作为一个正直的人绝不能自己独享,经过激烈的颅内斗争,我决定把我私藏的十几个 T 的,阿不,十几个刷题网...
白话阿里巴巴Java开发手册高级篇
不久前,阿里巴巴发布了《阿里巴巴Java开发手册》,总结了阿里巴巴内部实际项目开发过程中开发人员应该遵守的研发流程规范,这些流程规范在一定程度上能够保证最终的项目交付质量,通过在时间中总结模式,并推广给广大开发人员,来避免研发人员在实践中容易犯的错误,确保最终在大规模协作的项目中达成既定目标。 无独有偶,笔者去年在公司里负责升级和制定研发流程、设计模板、设计标准、代码标准等规范,并在实际工作中进行...
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
redis分布式锁,面试官请随便问,我都会
文章有点长并且绕,先来个图片缓冲下! 前言 现在的业务场景越来越复杂,使用的架构也就越来越复杂,分布式、高并发已经是业务要求的常态。像腾讯系的不少服务,还有CDN优化、异地多备份等处理。 说到分布式,就必然涉及到分布式锁的概念,如何保证不同机器不同线程的分布式锁同步呢? 实现要点 互斥性,同一时刻,智能有一个客户端持有锁。 防止死锁发生,如果持有锁的客户端崩溃没有主动释放锁,也要保证锁可以正常释...
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
Nginx 原理和架构
Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器。Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。 Nginx 的整体架构 Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处...
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1...
Java世界最常用的工具类库
Apache Commons Apache Commons有很多子项目 Google Guava 参考博客
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员...
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC...
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下...
为什么要学数据结构?
一、前言 在可视化化程序设计的今天,借助于集成开发环境可以很快地生成程序,程序设计不再是计算机专业人员的专利。很多人认为,只要掌握几种开发工具就可以成为编程高手,其实,这是一种误解。要想成为一个专业的开发人员,至少需要以下三个条件: 1) 能够熟练地选择和设计各种数据结构和算法 2) 至少要能够熟练地掌握一门程序设计语言 3) 熟知所涉及的相关应用领域的知识 其中,后两个条件比较容易实现,而第一个...
Android 9.0 init 启动流程
阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android本篇文章主要介绍Android开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:一、启动流程概述一、 启动流程概述Android启动流程跟Linux启动类似,大致分为如下五个阶段。1.开机上电,加载固化的ROM。2.加载BootLoader,拉起Android OS。3.加载Uboot,初始外设,引导Kernel启动等。...
8年经验面试官详解 Java 面试秘诀
作者 |胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。 Java程序员准备和投递简历的实...
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车?某胡同口的煎饼摊一年能卖出多少个煎饼?深圳有多少个产品经理?一辆公交车里能装下多少个乒乓球?一个正常成年人有多少根头发?这类估算问题,被称为费米问题,是以科学家费米命名的。为什么面试会问这种问题呢?这类问题能把两类人清楚地区分出来。一类是具有文科思维的人,擅长赞叹和模糊想象,它主要依靠的是人的第一反应和直觉,比如小孩...
前后端分离,我怎么就选择了 Spring Boot + Vue 技术栈?
前两天又有小伙伴私信松哥,问题还是职业规划,Java 技术栈路线这种,实际上对于这一类问题我经常不太敢回答,每个人的情况都不太一样,而小伙伴也很少详细介绍自己的情况,大都是一两句话就把问题抛出来了,啥情况都不了解,就要指出一个方向,这实在是太难了。 因此今天我想从我学习 Spring Boot + Vue 这套技术栈的角度,来和大家聊一聊没有人指导,我是如何一步一步建立起自己的技术体系的。 线上大...
17张图带你解析红黑树的原理!保证你能看懂!
二叉查找树 由于红黑树本质上就是一棵二叉查找树,所以在了解红黑树之前,咱们先来看下二叉查找树。 二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若任意结点的...
so easy! 10行代码写个"狗屁不通"文章生成器
前几天,GitHub 有个开源项目特别火,只要输入标题就可以生成一篇长长的文章。 背后实现代码一定很复杂吧,里面一定有很多高深莫测的机器学习等复杂算法 不过,当我看了源代码之后 这程序不到50行 尽管我有多年的Python经验,但我竟然一时也没有看懂 当然啦,原作者也说了,这个代码也是在无聊中诞生的,平时撸码是不写中文变量名的, 中文...
知乎高赞:中国有什么拿得出手的开源软件产品?(整理自本人原创回答)
知乎高赞:中国有什么拿得出手的开源软件产品? 在知乎上,有个问题问“中国有什么拿得出手的开源软件产品(在 GitHub 等社区受欢迎度较好的)?” 事实上,还不少呢~ 本人于2019.7.6进行了较为全面的回答,对这些受欢迎的 Github 开源项目分类整理如下: 分布式计算、云平台相关工具类 1.SkyWalking,作者吴晟、刘浩杨 等等 仓库地址: apache/skywalking 更...
MySQL数据库总结
一、数据库简介 数据库(Database,DB)是按照数据结构来组织,存储和管理数据的仓库。 典型特征:数据的结构化、数据间的共享、减少数据的冗余度,数据的独立性。 关系型数据库:使用关系模型把数据组织到数据表(table)中。现实世界可以用数据来描述。 主流的关系型数据库产品:Oracle(Oracle)、DB2(IBM)、SQL Server(MS)、MySQL(Oracle)。 数据表:数...
记一次腾讯面试:进程之间究竟有哪些通信方式?如何通信? ---- 告别死记硬背
有一次面试的时候,被问到进程之间有哪些通信方式,不过由于之前没深入思考且整理过,说的并不好。想必大家也都知道进程有哪些通信方式,可是我猜很多人都是靠着”背“来记忆的,所以今天的这篇文章,讲给大家详细着讲解他们是如何通信的,让大家尽量能够理解他们之间的区别、优缺点等,这样的话,以后面试官让你举例子,你也能够顺手拈来。 1、管道 我们来看一条 Linux 的语句 netstat -tulnp | gr...
20行Python代码爬取王者荣耀全英雄皮肤
引言 王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了。我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成。 准备工作 爬取皮肤本身并不难,难点在于分析,我们首先得得到皮肤图片的url地址,话不多说,我们马上来到王者荣耀的官网: 我们点击英雄资料,然后随意地选择一位英雄,接着F12打开调试台,找到英雄原皮肤的图片...
傲慢与无知,请警惕伪需求的陷阱!
前言 你是否有这样的思考,与人争辩时,明明对于自己的认知和立场有着清楚的认识,同样身为人类的另一个人却完全无法接纳你的观点,这是为什么。 人类作为一个高等生物智能机器人,具备自我内存优化的能力,这一能力增加了人类的模糊处理能力从而出现了创造性,同时却削弱了人类的真理认知能力。 个体认知范围是有限的,个体只会做出认知范围内所接受的举动 青少年的时候,我常常有一种自己是特别的,是与众不同的感觉。而这种...
中年危机,35 岁定律,见鬼去吧!
中年危机,35 岁定律,相信你都听说过,每次触及还会让你感到丝丝焦虑,毕竟时间这把杀猪刀不会放过任何一个人。中年危机或 35 岁定律是客观存在的,你迟早都会遭遇的,那你是否有信心战胜它呢? 中年危机之所以让人害怕,一则是你没有把握打赢这场遭遇战,再则中年是一个输不起的阶段。古人云:知己知彼,百战不殆。恐惧,主要源自对敌人和自己的不了解,不知道敌人的优劣势,也不清楚自己的长短板,常常以己之所短攻彼...
腾讯架构师,为了家庭去小厂,一个月后主动离职:不做中台就是等死
今天咱们第一课,来讲讲大家一直很关注的数据中台。其实,数据中台也是企业数据管理的一部分,甚至可以说是很重要的一部分。 一、什么是中台? 这其实是一个老生常谈的概念了,中台,顾名思义,就是在起中间作用的东西,前有前台,后有后台。 对于中台每个人可能有不同的理解,行业里也没有严格的定义,但我更认同其中一个说法就是:中台是企业级能力复用的平台。 那这句话怎么理解呢? 既然核心是能力复...
用sql演示脏读,不可重复读,幻读,不怕你看不懂
介绍 要聊事务,不可避免的要提到数据库事务的四大特性 原子性(Atomic) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability) 今天只聊隔离性,其他的比较好理解,建议看推荐阅读中关于事务的讲解。 先放一个表格,看看4个隔离级别会出现的各种问题,网上的解释一大堆。看完后还是一脸蒙蔽,感觉懂了,又好像没懂。因为没有具体的演示例子,索性自己尝试复现这几个问题...
张小龙-年薪近3亿的微信之父,他是如何做到的?
张小龙生于湖南邵东魏家桥镇, 家庭主要特点:穷。 不仅自己穷,亲戚也都很穷,可以说穷以类聚。爷爷做过铜匠,总的来说,标准的劳动阶级出身。 家有兄弟两人, 一个小龙,一个小虎。 小虎好动,与邻里打成一片, 小龙好静,喜好读书。 “文静的像个妹子。”张小龙的表哥如是说。 穷文富武,做个读书郎是个不错的选择。 87年至94年, 华中科技大学本硕连读。 本科就读电信系, 不喜欢上课...
阿里靠什么武功秘籍渡过“双十一“的天量冲击
双十一大概会产生多大的数据量呢,可能大家没概念,举个例子央视拍了这么多年电视新闻节目,几十年下来他存了大概80P的数据。而今年双11一天,阿里要处理970P的数据,做为一个IT人,笔者认为今年”双十一“阿里最大的技术看点有有以下两个: 阿里的数据库,也就是刚刚拿下TPC冠军的OcceanBase,处理峰值也达到了骇人听闻的6100万次/秒, 阿里核心系统百分百上云了。 如果把信息系统比做一个武...
西游记团队中如果需要裁掉一个人,会先裁掉谁?
2019年互联网寒冬,大批企业开始裁员,下图是网上流传的一张截图: 裁员不可避免,那如何才能做到不管大环境如何变化,自身不受影响呢? 我们先来看一个有意思的故事,如果西游记取经团队需要裁员一名,会裁掉谁呢,为什么? 西游记团队组成: 1.唐僧 作为团队teamleader,有很坚韧的品性和极高的原则性,不达目的不罢休,遇到任何问题,都没有退缩过,又很得上司支持和赏识(直接得到唐太宗的任命,既给袈...
相关热词 c# 引用mysql c#动态加载非托管dll c# 两个表数据同步 c# 返回浮点json c# imap 链接状态 c# 漂亮字 c# 上取整 除法 c#substring c#中延时关闭 c#线段拖拉
立即提问