记录一次bug解决过程:规范变量名称和mybatis的使用以及代码优化
一、总结
- Mybatis中当parameterType为基本数据类型的时候,统一采用_parameter来代替基本数据类型变量。
- Mybatis中resultMap返回一个对象,resultType返回一个Map简单数据类型(由于需要缓存到JVM中)的映射关系。
- String类型转Integer类型;String类型转int类型用到的方法是不一样的。
- 方法入口处第一行写new Date(),防止时间在23:59:59跨界对逻辑带来影响。
- 考虑到上线app_resource表忘记配置供应商比例,在代码中逻辑中注意要加入空指针判断,增强代码健壮性。
- 核心代码处要加注释,关键代码处要打日志,业务逻辑执行失败要考虑是否需要告警邮件。
- 变量命名要规范;测试工单的工单标题命名要规范。
- 代码逻辑中有if使用的地方,尽量想想else使用的场景,保证逻辑严谨性。
- VPN软件的使用;热部署的使用(http://docs.alibaba-inc.com/)。
二、Bug描述:Mybatis中parameterType使用
mapper层中使用parameterType="java.lang.Integer"基本类型,代码报错:
//org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException:
// There is no getter for property named 'siteId' in 'class java.lang.Integer'
解决办法,当入参为基本数据类型的使用,使用_parameter代替基本数据类型,如下:
<select id="getRulesInfoBysiteId" parameterType="java.lang.Integer" resultMap="RulesMap" >
SELECT
a.site_id,
a.site_name,
b.id AS city_id,
b.`name` AS city_name,
c.id AS region_id,
c.`name` AS region_name
FROM
idc_site a,
city b,
area c
WHERE
a.region = c.`name`
AND a.city = b.`name`
AND a.is_deleted = 'n'
AND b.is_deleted = 'n'
AND c.is_deleted = 'n'
<if test="_parameter != null">
AND a.site_id = #{_parameter,jdbcType=INTEGER}
</if>
</select>
或者在mapper层的接口中,给这个方法的参数加上@param(value=“siteId”),这样就能在.xml中使用#{siteId,jdbcType=INTEGER}了,仅使用于基本数据类型。
//mapper层对应的接口中必须加@Resource注解,否则在Dao层注入*Ext会失败
@Resource
public interface SiteMapperExt extends SiteMapper {
//mapper层对应的接口中加mybatis提供的注解@Param("siteId")
public RulesInfo getRulesInfoBysiteId(@Param("siteId")Integer siteId);
}
更多使用详情请看最后附文。
三、Bug描述:
/**
* 自动分配物流供应商
*/
@Override
public void autoAssignSupplier(RuleInfos ruleInfos, String deviceType, WorkOrderMain workOrder, int amounts) { // 精确匹配规则制定 物流供应商
LogisticsAssignRules bean = getExactMatchSPId(ruleInfos.getSourceRegionId(), ruleInfos.getTargetRegionId(),
ruleInfos.getSourceCityId(), ruleInfos.getTargetCityId(),
ruleInfos.getSourceSiteName(), ruleInfos.getTargetSiteName(),
deviceType, amounts);
if (null == bean) {
// 按比例规则制定物流供应商
Map<String, String> supplierRatesMap = getSpRates();
Map<String, String> logicOf90DaysBefore = getAssignRates();
String supplierId = getSupplierIdBy90Days(supplierRatesMap, logicOf90DaysBefore, amounts);
logisticsWorkOrderBo.LogisticsAssigned(workOrder, WorkOrderStatsCst.LogisticsOrderState.unassigned,
supplierId, getSpRatesDesc(), WorkOrderCst.DEFAULT_VALUE_YES);
logger.info("auto assign supplier as rates,supplierId = {}, description = {}", supplierId, getSpRatesDesc());
} else {
// 精确匹配,直接分配物流供应商
logisticsWorkOrderBo.LogisticsAssigned(workOrder, WorkOrderStatsCst.LogisticsOrderState.unassigned,
bean.getSpId().toString(), bean.getRuleJsonVal(),
WorkOrderCst.DEFAULT_VALUE_YES);
logger.info("auto assign supplier start as rules, supplierId = {}, description = {}",
bean.getSpId().toString(), getSpRatesDesc());
}
}
在接口调用中,当传递属性过多的时候,可以考虑用对象来传递,方便以后的扩展。如本代码中,当后续添加规则时,需要更新方法。另外对于公用的东西,尽量维护在静态枚举值中。
四、Bug描述:方法入口处统一获取当前时间new Date()
在代码中的时间要作为条件来筛选数据,如果同一个方法中,在多个地方出现new Date(),算上程序执行的纳秒级别的时间,可能在当前日期的“23:59:59 纳秒”产生跨界时间的问题,给代码造成概率极低的隐患。
SELECT
d.sp_id,
COUNT(a.sn) AS asset_counts
FROM
idc_asset_list a
LEFT JOIN idc_work_order_main b ON a.order_id = b.id
LEFT JOIN idc_order_atomic_list c ON c.order_id = b.id
LEFT JOIN idc_atomic_logistics d ON d.atomic_id = c.atomic_id
WHERE
a.is_deleted = 'n'
AND b.is_deleted = 'n'
AND c.is_deleted = 'n'
AND d.is_deleted = 'n'
AND d.sp_id IS NOT NULL
AND b.gmt_create < CONCAT('2016-08-04', '23:59:59')
AND b.gmt_create > date_sub(
'2016-08-04 00:00:00',
INTERVAL 3 MONTH
)
AND (
b.state != 'cancle'
OR b.sub_state != 'cancle'
)
GROUP BY
d.sp_id
ORDER BY
sp_id DESC
因为要将上述数据缓存到JVM中,数据结构在集群中的一台机器上只维护一份。一天最多查询8次。
使用到的SQL如下:
<select id = "getLogisticsList90DaysBefore" parameterType="java.lang.String" resultType ="java.util.Map">
SELECT
d.sp_id AS spId,
COUNT(a.sn) AS assetCounts
FROM
idc_asset_list a
LEFT JOIN idc_work_order_main b ON a.order_id = b.id
LEFT JOIN idc_order_atomic_list c ON c.order_id = b.id
LEFT JOIN idc_atomic_logistics d ON d.atomic_id = c.atomic_id
WHERE
a.is_deleted = 'n'
AND b.is_deleted = 'n'
AND c.is_deleted = 'n'
AND d.is_deleted = 'n'
AND d.sp_id IS NOT NULL
AND (b.state != 'cancle' OR b.sub_state != 'cancle')
<if test = "_parameter != null and _parameter !=''">
AND a.gmt_create <= CONCAT(#{yesterday},' 23:59:59')
AND a.gmt_create >= DATE_SUB(CONCAT(#{yesterday},' 00:00:00'), INTERVAL 3 MONTH)
</if>
GROUP BY
d.sp_id
ORDER BY
sp_id DESC
</select>
mapper层的代码中,我们使用了mysql函数date_sub(concat(""), interval 3 month),并且返回resultType="java.util.Map",我们使用结构List<String,Map<String,Object>>结构来接收查询结果,而没有采用resultMap封装对象来接收结果。
SQL执行之后的返回结果为list,通过断点跟踪获悉sp_id为Integer类型,asset_counts为Long类型。
//获取spId
Integer spId = map.get("spId");
//获取assetCounts
Long assetCounts = map.get("assetCounts");
故使用如下代码获取查询结果,但是代码中封装了数据类型,所以统一采用Object来获取。
五、Bug描述:考虑到线上缺失配置文件,添加空指针判断;为程序健壮性,必须在前后端同时对参数完整性作出校验。
/**
* 校验参数的完整性 {设备类型与数量必填,用于规则匹配校验}
*/
private void checkParameters(AssignSupplierRulesDTO dto) {
// 数量合理性校验
if (StringUtils.isNotBlank(dto.getAssetNum())) {
if (dto.getAssetNum().toCharArray().length <= 1) {
throw new ServiceException(ErrorCode.Params_Lost);
} else {
if (!(StringUtils.isNumeric(dto.getAssetNum().substring(1)))) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
if (!("><=≤≥≠".contains(dto.getAssetNum().substring(0, 1)))) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
// 供应商必填
if (null == dto.getSpId()) {
throw new ServiceException(ErrorCode.Params_Lost);
}
// 规则名称必填
if (StringUtils.isBlank(dto.getRuleName())) {
throw new ServiceException(ErrorCode.Params_Lost);
} // 当指定规则类型的时候,关联性校验
if (StringUtils.isNotBlank(dto.getRuleType())) {
// 同城校验
if (dto.getRuleType().equals(WorkOrderCst.RelocationType.SameCity.name())) {
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceCity()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceCity()))) {
if (dto.getSourceCity() != dto.getTargetCity()) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
// 同区域内校验
if (dto.getRuleType().equals(WorkOrderCst.RelocationType.RegionalIn)) { if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceRegion()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetRegion()))) {
if (StringUtils.isNotBlank(dto.getSourceRegion()) && StringUtils.isNotBlank(dto.getTargetRegion())) {
// 区域必须相等
if (!(dto.getSourceRegion().equals(dto.getTargetRegion()))) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceCity()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetCity()))) {
if (StringUtils.isNotBlank(dto.getSourceCity()) && StringUtils.isNotBlank(dto.getTargetCity())) {
if (!addressBo.whetherCityInTheSameArea(dto.getSourceCity(), dto.getTargetCity())) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceSite()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetSite()))) {
if (StringUtils.isNotBlank(dto.getSourceSite()) && StringUtils.isNotBlank(dto.getTargetSite())) {
if (!addressBo.whetherSiteInTheSameArea(dto.getSourceSite(), dto.getTargetSite())) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
}
// 不同区域的校验
if (dto.getRuleType().equals(WorkOrderCst.RelocationType.RegionalOut)) {
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceRegion()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetRegion()))) {
if (StringUtils.isNotBlank(dto.getSourceRegion()) && StringUtils.isNotBlank(dto.getTargetRegion())) {
if (dto.getSourceRegion().equals(dto.getTargetRegion())) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceCity()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetCity()))) {
if (StringUtils.isNotBlank(dto.getSourceCity()) && StringUtils.isNotBlank(dto.getTargetCity())) {
if (addressBo.whetherCityInTheSameArea(dto.getSourceCity(), dto.getTargetCity())) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
if (!(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getSourceSite()))
&& !(WorkOrderCst.MATCH_ALL_PARAMETERS.equals(dto.getTargetSite()))) {
if (StringUtils.isNotBlank(dto.getSourceSite()) && StringUtils.isNotBlank(dto.getTargetSite())) {
if (addressBo.whetherSiteInTheSameArea(dto.getSourceSite(), dto.getTargetSite())) {
throw new ServiceException(ErrorCode.Params_Invalid);
}
}
}
}
}
}
六、Bug描述:String转Integer;String转int的熟练使用。
public class Test {
public static void main(String[] args) {
String number = "520";
Integer a = 521;
int b = 522; //String转Integer
Integer.valueOf(number); //String转int
Integer.parseInt(number);
new Integer(number).intValue(); //Integer转String
a.toString(); //Integer转int
a.intValue(); //int转String
String.valueOf(b);
Integer.toString(b);
String str = "" + b; //int转Integer
new Integer(b); //String转BigDecimal
new BigDecimal(number);
//获取今天日期
new Date(System.currentTimeMillis()); // Fri Aug 05 20:16:07 CST 2016
DateFormat.getDateInstance().format(new Date()); // 2016-8-5
}
}
七、List和数组的转换
public class Test {
public static void main(String[] args) {
String[] family = { "XuG", "XuX", "GaiZ", "LianW" };
List<String> list = new ArrayList<String>(Arrays.asList("XuG", "XuX", "GaiZ", "LianW")); //数组转list
List<String> list_01 = new ArrayList<String>(Arrays.asList(family)); //list转数组
String[] str = (String[])list.toArray();
}
}
八、Bug描述:变量命名规范。
变量的命名规范要有意义,在数据库建表,创建java bean的时候,一定要保证单词使用的正确性。如label和lable;region和regin。要注意到变量的命名可能跟数据库的关键字或java的关键字有冲突,可以采用下划线的原则处理关键字冲突。
九、Bug描述:逻辑严谨性。
private String getSupplierIdBy90Days(Map<String, String> supplierRatesMap, Map<String, String> logicOf90DaysBefore,
int dispatchNum) {
int ratesCount = 0, dispatchCount = 0;
for (String spId : supplierRatesMap.keySet()) {
ratesCount = ratesCount + Integer.parseInt(supplierRatesMap.get(spId));
}
for (String spId : logicOf90DaysBefore.keySet()) {
dispatchCount = dispatchCount + Integer.parseInt(logicOf90DaysBefore.get(spId));
}
Map<String, String> idealizedMap = new HashMap<String, String>();
for (String spId : supplierRatesMap.keySet()) {
Integer dispathNum = (dispatchCount * Integer.parseInt(supplierRatesMap.get(spId))) / ratesCount;
idealizedMap.put(spId, dispathNum.toString());
}
int gap = -1;
String supplierId = StringUtils.EMPTY;
if (CollectionUtils.isNotEmpty(logicOf90DaysBefore.keySet())) {
for (String spId : logicOf90DaysBefore.keySet()) {
if (null != idealizedMap.get(spId)) {
int mix = Integer.parseInt(idealizedMap.get(spId))
- Integer.parseInt(logicOf90DaysBefore.get(spId));
if (mix < gap) {
gap = mix;
supplierId = spId;
}
} else {
supplierId = spId; // 新添加的供应商比例
}
}
} else {
supplierId = new ArrayList<String>(supplierRatesMap.keySet()).get(0);
}
return supplierId;
}
有判断if条件的地方,要考虑到else的可能出现情况,尤其是if else 嵌套多层的时候,可能某些else的情况遗漏,会给程序带来问题。如上述代码中的else的缺失,可能在“新添加供应商比例”的情况下,出现没有分配供应商的情况。
十、VPN工具
VPN工具下载使用:Cisco AnyConnect VPN Client 64位下载
附:Mybatis中parameterType和resultType的相关用法
1、parameterType用法,parameterType的传入参数类型大致分为如下几类:
基本数据类型(_parameter接收参数)
<!-- mapper对应接口层 -->
public RulesInfo getRulesInfoBysiteId(Integer siteId); <!-- mapper中指定Integer类型,用_parameter来接收 -->
<select id="getRulesInfoBysiteId" parameterType="java.lang.Integer" resultMap="RulesMap" >
SELECT
a.site_id,
a.site_name,
b.id AS city_id,
b.`name` AS city_name,
c.id AS region_id,
c.`name` AS region_name
FROM
idc_site a,
city b,
area c
WHERE
a.region = c.`name`
AND a.city = b.`name`
AND a.is_deleted = 'n'
AND b.is_deleted = 'n'
AND c.is_deleted = 'n'
<if test="_parameter != null">
AND a.site_id = #{_parameter,jdbcType=INTEGER}
</if>
</select>
数组类型(foreach中的collection必须是array,不管变量的具体名称是什么。如下面变量名为ids,collection却是array)
<!-- mapper对应接口层:根据工单角色获取有权限的机房 -->
public List<User> findUserListByIdList(int[] ids); <!-- mapper中指定java.util.List类型,一般用于MySQL中IN语句中 -->
<select id="findUserListByIdList" parameterType="java.util.HashList" resultType="User">
select * from user
<where>
user.ID in (
<foreach item="guard" index="index" collection="array" separator=",">
#{guard}
</foreach>
)
</where>
</select>
List类型(单独传入list时,foreach中的collection必须是list,不管变量的具体名称是什么。比如代码中变量名为staffIds,collection中确实list)
<!-- mapper对应接口层 -->
public List<IdcStaff> selectStaffsbyIdnumbers(List<String> staffIds); <!-- mapper中指定java.util.List类型,一般用于MySQL中IN语句中 -->
<select id="selectStaffsbyIdnumbers" parameterType="java.util.List" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM idc_staff where id_number IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
AND IS_DELETED='n'
ORDER BY staff_status
</select>
Map类型(MAP中有list或array时,foreach中的collection必须是具体list或array的变量名。同上)
<!--*BoImpl.java层构造传入的map参数-->
public List<SiteUserVo> getSiteUserPermission(String siteName, Long roleId, String workNo) {
Map<String, Object> siteByUser = new HashMap<String, Object>();
if (StringUtils.isNotBlank(siteName) && !"".equals(siteName.trim())) {
siteByUser.put("site", siteName);
}
if (null != roleId && 0 != roleId) {
siteByUser.put("roleId", roleId);
}
if (StringUtils.isNotBlank(workNo) && !"".equals(workNo.trim())) {
siteByUser.put("workNo", workNo);
}
return siteMapperExt.getSiteUserPermission(siteByUser);
} <!-- mapper对应接口层:根据工单角色获取有权限的机房 -->
public List<SiteUserVo> getSiteUserPermission(Map siteByUser); <!-- mapper中指定java.util.List类型,一般用于MySQL中IN语句中 -->
<select id="getSiteUserPermission" parameterType="java.util.HashMap" resultMap="SiteUserVoMap">
SELECT
i.site_name,
t.role_id,
h.work_no
FROM
idc_site_user t
LEFT JOIN idc_site i ON t.site_id = i.site_id
LEFT JOIN app_user h ON t.user_id = h.id
WHERE
t.IS_DELETED = 'n'
AND h.IS_DELETED = 'n'
AND i.IS_DELETED = 'n'
<IF test = "site!=null" >
AND i.site_name = #{site}
</IF >
<IF test = "roleId!=null" >
AND t.role_Id = #{roleId}
</IF >
<IF test = "workNo!=null" >
AND h.work_no = #{workNo}
</IF >
</select>
Java对象
<!-- mapper对应接口层:根据工单角色获取有权限的机房 -->
List<AssignRulesVo> selectByQuery(QueryAssignRulesrDo query); <!-- mapper中指定对象类型,对象的属性名可以直接使用;如果要在SQL中判定对象是否为空,还要用_parameter -->
<select id="selectByQuery" parameterType="com.alibaba.tboss.dal.mysql.workOrder.query.QueryAssignRulesrDo" resultMap="BaseResult">
SELECT
a.id,
a.is_valid,
a.rule_lable,
a.rule_name,
a.type,
b.sp_id,
b.sp_name,
a.rule_content,
c.user_name,
a.gmt_modified,
a.ordering,
a.rule_json_val
FROM
idc_logistics_assign_rules a
LEFT JOIN app_user c on c.work_no=a.modifier and c.is_deleted='n',
idc_sp_info b
WHERE
a.is_deleted = 'n'
AND b.is_deleted = 'n'
AND a.sp_id = b.sp_id
<if test="ruleId != null">
AND a.id = #{ruleId,jdbcType=BIGINT}
</if>
<if test="ruleName != null and ruleName != ''">
AND a.rule_name IN (${ruleName})
</if>
ORDER BY ordering asc
<if test="doPage == true">
limit #{skip,jdbcType=INTEGER}, #{take,jdbcType=INTEGER}
</if>
</select>
补充${}会导致SQL注入攻击,不建议使用。
//取值的时候用的是#{}。它具体的意思是告诉MyBatis创建一个预处理语句参数。
//使用JDBC,这样的一个参数在SQL中会由一个“?”来标识,并被传递到一个新的预处理语句中。 //一般情况下,我们采用#{}取值,产生预处理语句,但是有时我们可能不希望Mybatis来帮我们预处理。
//${columnName},这里MyBatis不会修改或转义字符串。而是直接拼接到SQL字符串后面。
记录一次bug解决过程:规范变量名称和mybatis的使用以及代码优化的更多相关文章
- 记录一次bug解决过程:else未补全导致数据泄露和代码优化
一.总结 快捷键ctrl + alt + 四个方向键 --> 倒置屏幕 未补全else逻辑,倒置查询数据泄露 空指针是最容易犯的错误,数据的空指针,可以普遍采用三目运算符来解决 SVN冲突解决关 ...
- 记录一次bug解决过程:数据迁移
一 总结 不擅长语言表达,勤于沟通,多锻炼 调试MyBatis中SQL语法:foreach 问题:缺少关键字VALUES.很遗憾:它的错误报的让人找不着北. 二 BUG描述:MyBatis中批量插入数 ...
- 记录一次bug解决过程:git深入学习和JDK8新特性
一 总结 熟悉廖雪峰git基础; 由于git跟踪的是修改,而不是版本号:因此对于修改撤销的操作,文件在eclipse中依旧有>修改标记,这点不同于svn. 二 BUG描述:熟悉Git基础 在Gi ...
- 记录一次bug解决过程:velocity中获取url中的参数
一.总结 在Webx的Velocity中获取url中参数:$rundata.getRequest().getParameter('userId') 在Webx项目中,防止CSRF攻击(Cross-si ...
- 记录一次bug解决过程:可维护性和性能优化
一.总结 使用某些变量的地方在2次以上的,强烈建议使用枚举值来维护变量,日后方便扩展. 查数据库的方法调用,能合并就净量去合并. 二.Bug描述 枚举变量的维护以及方法使用: public class ...
- 记录一次bug解决过程:mybatis中$和#的使用
一.总结 mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数.动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因.mybatis在对sql语句进行预编 ...
- 记录一次bug解决过程:eclipse集成lombok插件
一 总结 eclipse集成插件lombok: 启动Spring Boot项目: sublime全局搜索关键字:ctrl + shift + F JDK8中的lambda表达式使用 二 BUG描述:集 ...
- 记录一次bug解决过程:eclipse Installed JREs 配置引出的问题
一 总结 eclipse Installed JREs 配置引出的问题:编译以来JDK,不是JRE spring boot内嵌tomcat运行程序,tomcat:run 二 Bug描述:eclipse ...
- 记录一次bug解决过程:resultType和手动开启事务
一.总结 二.BUG描述:MyBatis中resultType使用 MyBatis中的resultType类似于入参:parameterType.先看IDCM项目中的实际使用案例代码,如下: // L ...
随机推荐
- C#创建、安装、卸载、调试Windows Service(Windows 服务)的简单教程
前言:Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...
- 品牌营销:不要Beat,要逼格!
品牌营销:不要Beat,要逼格! 奥美的创始人大卫·奥格威说,广告营销应当是"具有风度的推销产品".而当下的营销手段,"风度"早已被抛之脑后, ...
- 给缺少Python项目实战经验的人
我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- Spring5:@Autowired注解、@Resource注解和@Service注解
什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分 ...
- Ford-Fulkerson 最大流算法
流网络(Flow Networks)指的是一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 均有一非负容量 c(u, v) ≥ 0.如果 (u, v) ∉ E 则可以规定 c(u, ...
- APP开放源码第一弹《纳豆》
2016年7月2日,这是一个风轻云淡的日子,DeviceOne平台的用户Star将自己经过一段时间研发的产品通过官方的渠道开源出来,这不仅是对自己设计的高度自信.更是想体现一下自己对于DeviceOn ...
- 工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧
之前一篇<工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)!> 看到很多朋友回复和支持,非常感谢,尤其是一些拍砖的喷油,感谢你们的批评,受益良多. 我第一份工作便是W ...
- jQuery +ajax +json+实现分页
正文 首先我们创建一般处理程序,来读取数据库中内容,得到返回值. 创建文件,GetData.ashx. 我这里是用的存储过程,存储过程会再下面粘出来,至于数据只是实例,你们可根据需求自行读取数据 代码 ...
- 5.SVM核函数
核函数(Kernels) 定义 1.1 (核或正定核) 设是中的一个子集,称定义在上的函数是核函数,如果存在一个从到Hilbert空间的映射 使得对任意的,都成立.其中表示Hilbert空间中的内积. ...