Online Judge(OJ)搭建——3、MVC架构
Model

Model 层主要包含数据的类,这些数据一般是现实中的实体,所以,Model 层中类的定义常常和数据库 DDL 中的 create 语句类似。
通常数据库的表和类是一对一的关系,但是有的时候由于需求变化或者方便起见,Model 层的类有时不和数据库中表相互对应。比如面向对象之组合属性,在 Java 中可以用一个类组合另一个类,表示测试信息、对应多组测试用例的组合,(正常情况下,应该是一张表而不是两张表),而数据库是用两张表存储数据,利用外键关系表示测试信息、对应多组测试用例的关系。



由于数据繁多,为了简化对象的映射,不使用JDBC,而采用持久化框架 MyBatis。
MyBatis 首先需要配置数据源:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- property from external resources -->
<properties resource="config/mybatis/applications.properties"/>
<!-- settings -->
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false" />
<setting name="autoMappingBehavior" value="PARTIAL" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="25000" />
<setting name="safeRowBoundsEnabled" value="false" />
<setting name="mapUnderscoreToCamelCase" value="false" />
<setting name="localCacheScope" value="SESSION" />
<setting name="jdbcTypeForNull" value="OTHER" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode ,toString" />
-->
</settings>
<!-- type aliases(full class name -> simple class name) -->
<typeAliases>
<!--
<typeAlias alias="Student" type="com.mybatis3.domain.Student" />
-->
<package name="per.piers.onlineJudge.model"/>
</typeAliases>
<!-- type handlers -->
<typeHandlers>
<typeHandler handler="per.piers.onlineJudge.handler.SexTypeHandler" javaType="per.piers.onlineJudge.model.Sex"
jdbcType="BOOLEAN"/>
</typeHandlers>
<!-- environment -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<environment id="production">
<transactionManager type="MANAGED"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/jdbc/mybatis"/>
</dataSource>
</environment>
</environments>
<!-- mappers location -->
<mappers>
<!--
<mapper url="file:///D:/mybatisdemo/app/mappers/TutorMapper.xml" />
<mapper class="com.mybatis3.mappers.TutorMapper" />
-->
<mapper resource="mapper/UserMapper.xml"/>
<mapper resource="mapper/QuestionMapper.xml"/>
<mapper resource="mapper/CategoryMapper.xml"/>
<mapper resource="mapper/TestDataMapper.xml"/>
<mapper resource="mapper/TestInfoMapper.xml"/>
<mapper resource="mapper/ScoreMapper.xml"/>
<mapper resource="mapper/AdvisorMapper.xml"/>
</mappers>
</configuration>
之后创建工厂对象,再用它创建数据访问对象(DataAccessObject,DAO):
@Bean
public SqlSessionFactory sqlSessionFactory() throws IOException {
ClassLoader classLoader = RootConfig.class.getClassLoader();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(classLoader.getResourceAsStream("config/mybatis/mybatis-config.xml"));
return sqlSessionFactory;
} @Autowired
@Bean
public DataAccessObject dataAccessObject(SqlSessionFactory sqlSessionFactory) {
return new DataAccessObject(sqlSessionFactory);
}
DAO 对象负责数据访问。首先以 Mapper 接口的方式定义访问数据库的函数,之后在 XML 文件中实现该函数,并提供具体实现(SQL 语句细节)。这样做的好处一方面是防止命名错误,传统 MyBatis 方式是根据函数名执行相关 SQL 语句的,不用接口书写很容易出错;另一方面有助于设计(接口)和实现分离,降低耦合性。
public interface UserMapper {
public int insertUser(@Param("user")User user);
public int updateUser(@Param("user")User user);
public int deleteUser(@Param("user") User user);
public User selectUser(@Param("user") User user);
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="per.piers.onlineJudge.mapper.UserMapper">
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="user.id">
INSERT INTO users (email, password, name, sex, role, enabled)
VALUES (#{user.email}, #{user.password}, #{user.name}, #{user.sex}, #{user.role}, #{user.enabled})
</insert>
<update id="updateUser" parameterType="User">
UPDATE users
<trim prefix="SET" suffixOverrides=",">
<if test="user.email != null">email = #{user.email},</if>
<if test="user.password != null">password = #{user.password},</if>
<if test="user.name != null">name = #{user.name},</if>
<if test="user.sex != null">sex = #{user.sex},</if>
<if test="user.role != null">role = #{user.role},</if>
<if test="user.enabled != null">enabled = #{user.enabled},</if>
</trim>
WHERE id = #{user.id}
</update>
<delete id="deleteUser" parameterType="User">
DELETE FROM users
WHERE id = #{user.id}
</delete>
<select id="selectUser" parameterType="User" resultMap="userResult">
SELECT *
FROM users
<if test="user != null">
<where>
<if test="user.email != null">email = #{user.email}</if>
</where>
</if>
</select>
<resultMap id="userResult" type="User">
<id column="id" property="id"/>
<result column="email" property="email"/>
<result column="password" property="password"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="enabled" property="enabled"/>
<result column="role" property="role"/>
</resultMap>
</mapper>
MyBatis的可以处理基本类型,但有些类型需要自定义转换,就需要 MyBatis 提供的 BaseTypeHandler 进行转换。首先编写 BaseTypeHandler(见下),之后在 MyBatis 配置文件中注册(见上)。
package per.piers.onlineJudge.handler; import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import per.piers.onlineJudge.model.Sex; import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class SexTypeHandler extends BaseTypeHandler<Sex> { @Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Sex sex, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i, sex.getId());
} @Override
public Sex getNullableResult(ResultSet resultSet, String s) throws SQLException {
int sex = resultSet.getInt(s);
if (resultSet.wasNull()) {
return null;
} else {
return Sex.getSexType(sex);
}
} @Override
public Sex getNullableResult(ResultSet resultSet, int i) throws SQLException {
int sex = resultSet.getInt(i);
if (resultSet.wasNull()) {
return null;
} else {
return Sex.getSexType(i);
}
} @Override
public Sex getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
int sex = callableStatement.getInt(i);
if (callableStatement.wasNull()) {
return null;
} else {
return Sex.getSexType(i);
}
} }
View


view 层主要是界面(页面)。这里主要是 JSP 页面,因为需要动态展示一些内容。其中还运用了 JavaScript 技术和 AJAX 技术,JavaScript 主要用作页面输入域校验,AJAX 主要用于异步提交需要更新的内容。
<%@page contentType="text/html; charset=UTF-8" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security" %>
<!DOCTYPE html>
<html>
<head>
<%@include file="../common/header.jspf" %>
<title>注册</title>
</head>
<body>
<%@include file="../common/navbar.jspf" %>
<div class="container">
<div class="page-header">
<h1>注册</h1>
</div>
<div class="form-signin" oninput="satisfySubmit()">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">邮箱*</span>
<input type="email" id="email" name="email" value="${email}" class="form-control" placeholder="邮箱长度不超过40个字符"
aria-describedby="basic-addon1" maxlength="40" required oninput="showEmailInputSuggestion()" disabled>
</div>
</div>
<div class="col-md-4">
<p id="emailError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon2">密码*</span>
<input type="password" id="password" name="password" class="form-control"
placeholder="密码长度不少于6个字符,不多于20个字符,只能包括数字和字母"
aria-describedby="basic-addon1" minlength="6" maxlength="20" required
oninput="showAllPasswordSuggestion()">
</div>
</div>
<div class="col-md-4">
<p id="passwordError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon3">确认密码*</span>
<input type="password" id="repassword" name="repassword" class="form-control" placeholder="再次输入密码"
aria-describedby="basic-addon1" minlength="6" maxlength="20" pattern="[\d\w]+" required
oninput="showAllPasswordSuggestion()">
</div>
</div>
<div class="col-md-4">
<p id="repasswordError" class="text-danger"></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon4">姓名</span>
<input type="text" id="name" name="name" class="form-control"
placeholder="你的姓名,可以很酷,不过最多只能有20个字符(中英皆可)"
aria-describedby="basic-addon1" maxlength="20">
</div>
</div>
<div class="col-md-4">
<p></p>
</div>
</div>
<br/>
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon" id="basic-addon5">性别</span>
<div class="form-control">
<div class="radio-inline">
<label>
<input type="radio" name="sex" id="optionsRadios1" value="MALE">
男
</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" name="sex" id="optionsRadios2" value="FEMALE">
女
</label>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<p></p>
</div>
</div>
<br/>
<input type="hidden" id="enabled" name="enabled" value="true"/>
<input type="hidden" id="role" name="role" value="user"/>
<input id="submit" type="button" value="不能注册,请检查相关项填写是否正确" class="btn btn-danger" disabled
onclick="registerUser()">
<br>
<p id="success"></p>
</div>
</div>
<%@include file="../common/footer.jspf" %>
<script src="${pageContext.request.contextPath}/js/user/user.js"></script>
<script src="${pageContext.request.contextPath}/js/user/register.js"></script>
</body>
</html>
function satisfySubmit() {
var submit = document.getElementById("submit");
if (isEmailValid() && isPasswordValid() && isRepasswordValid()) {
submit.setAttribute("type", "submit");
submit.setAttribute("value", "提交注册");
submit.setAttribute("class", "btn btn-success");
submit.removeAttribute("disabled")
} else {
submit.setAttribute("type", "button");
submit.setAttribute("value", "不能注册,请检查相关项填写是否正确");
submit.setAttribute("class", "btn btn-danger");
submit.setAttribute("disabled", "");
}
}
function registerUser() {
xmlhttp = new XMLHttpRequest();
if (xmlhttp != null) {
var email = document.getElementById("email").value;
var password = document.getElementById("password").value;
var name = document.getElementById("name").value;
var sexes = document.getElementsByName("sex");
var sex;
for (var i = 0; i < sexes.length; i++) {
if (sexes[i].checked) sex = sexes[i].value.toUpperCase();
}
var enabled = document.getElementById("enabled").value;
var role = document.getElementById("role").value;
var csrf = document.getElementsByName("_csrf")[0].value;
xmlhttp.onreadystatechange = stateChange;
xmlhttp.open("POST", window.location.pathname, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("&email=" + email + "&password=" + password + "&name=" + name + "&sex=" + sex + "&enabled=" + enabled + "&role=" + role + "&_csrf=" + csrf);
}
}
function stateChange() {
var success = document.getElementById("success");
if (xmlhttp.readyState == 4) { // 4 = "loaded"
if (xmlhttp.status == 200) { // 200 = "OK"
success.setAttribute("class", "text-success");
success.innerHTML = "注册成功";
alert("注册成功,点击确定进行登录")
window.location.href = getContextPath() + "/user/information"
} else if (xmlhttp.status == 409) {
success.setAttribute("class", "text-danger");
success.innerHTML = "用户邮箱已存在";
} else if (xmlhttp.status == 500) {
success.setAttribute("class", "text-danger");
success.innerHTML = "服务器可能出现了问题";
}
}
}
Controller
Controller 是 Model 和 View 的粘合剂。Model 的增删改查的操作由 Controller 负责,View 的显示由 Controller 负责。Controller 实质上是 Java EE 的 Servlet。
在 Spring MVC 中,首先配置相关 DispatcherServlet,之后再编写 Controller。
package per.piers.onlineJudge.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration
@EnableWebMvc
@ComponentScan("per.piers.onlineJudge.controller")
public class WebConfig extends WebMvcConfigurerAdapter { @Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setExposeContextBeansAsAttributes(true);
resolver.setSuffix(".jsp");
return resolver;
} @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
} }
package per.piers.onlineJudge.controller; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import per.piers.onlineJudge.model.User;
import per.piers.onlineJudge.util.DataAccessObject;
import per.piers.onlineJudge.util.ExcelUtil; import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet; @Controller
@RequestMapping("/testManager")
public class UserImportController { private DataAccessObject dao; @Autowired
public UserImportController(DataAccessObject dao) {
this.dao = dao;
} @RequestMapping("/import/user")
public String importUser() {
return "import/user";
} @RequestMapping(path = "/import/user", method = RequestMethod.POST)
public String importResult(@RequestPart("usersFile") MultipartFile usersFile, HttpServletRequest request, Model model) throws IOException {
String path = request.getSession().getServletContext().getRealPath("/") + "/tmp/" + usersFile.getOriginalFilename();
File file = new File(path);
file.getParentFile().mkdirs();
file.createNewFile();
usersFile.transferTo(file);
ExcelUtil excelUtil = new ExcelUtil();
HashSet<String> emails = excelUtil.readColumns(file, "用户邮箱");
try {
if (emails == null) {
model.addAttribute("failure", "读取列用户邮箱出错,可能是没有列用户邮箱");
} else {
User selectUser = new User();
selectUser.setEmail(((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
Integer uidAdmin = dao.selectUser(selectUser).getId();
HashMap<String, String> status = dao.importUser(emails, uidAdmin);
StringBuilder builder = new StringBuilder();
for (String key : status.keySet()) {
builder.append(String.format("%s,%s\n", key, status.get(key)));
}
model.addAttribute("success", builder.toString());
}
} catch (Exception e) {
model.addAttribute("failure", e.getMessage());
} finally {
return "import/result";
}
}
}
Spring 技术:这里的 Controller 是由 Spring MVC 提供的。本系统还设计了一个 ErrorController,用户异常处理的 Controller,返回错误的页面。
package per.piers.onlineJudge.controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class ErrorController { @RequestMapping(path = "/error/401")
public String error401() {
return "error/401";
} @RequestMapping(path = "/error/403")
public String error403() {
return "error/403";
} @RequestMapping(path = "/error/404")
public String error404() {
return "error/404";
} @RequestMapping(path = "/error/409")
public String error409() {
return "error/409";
} @RequestMapping(path = "/error/500")
public String error500() {
return "error/500";
} }
Spring 技术:异常的捕获和处理是由标有 @ControllerAdvice 注解的类处理,需要定义捕获的异常类型、如何处理(返回的 HTTP 状态码,返回的页面)。
package per.piers.onlineJudge.controller; import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import per.piers.onlineJudge.Exception.CRUDException;
import per.piers.onlineJudge.Exception.ExistenceException;
import per.piers.onlineJudge.Exception.ExpiryException; import javax.mail.MessagingException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter; @ControllerAdvice
public class GlobalExceptionHandler { @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
@ExceptionHandler(BadCredentialsException.class)
public String badCredentialsExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/401";
} @ResponseStatus(value = HttpStatus.FORBIDDEN)
@ExceptionHandler(value = {ExpiryException.class, IllegalArgumentException.class})
public String illegalStateExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/403";
} @ResponseStatus(value = HttpStatus.CONFLICT)
@ExceptionHandler(ExistenceException.class)
public String existenceExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/409";
} @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = {CRUDException.class, IOException.class, IllegalStateException.class, MessagingException.class, PersistenceException.class})
public String CRUDExceptionHandler(Exception e, Model model) {
model.addAttribute("exception", getExceptionMessage(e));
return "error/500";
} public String getExceptionMessage(Exception e) {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
return stringWriter.toString();
} }
Online Judge(OJ)搭建——3、MVC架构的更多相关文章
- 【深入Cocos2d-x】使用MVC架构搭建游戏Four
喜欢Four这个项目,就赶快在GitHub上Star这个项目吧! 喜欢我的文章,来微博关注我吧:王选易在学C艹 点我下载 项目起源 项目Logo: 下面是该游戏的项目地址,各位想参考源代码的同学可以到 ...
- 钟表维修管理系统技术解析(一) MVC架构搭建
钟表维修管理系统技术解析(一) MVC架构搭建 1.1新建项目 第一步:打开VS2010界面,点击左上角文件,点击新建,选择项目 1.1(图1) 第二步:点击网站Web类型,选择ASP.net MV ...
- 【JAVA】基于MVC架构Java技术荟萃案例演练
基于JAVA-MVC技术的顾客管理项目案例总结 作者 白宁超 2016年6月9日22:47:08 阅读前瞻:本文源于对javaweb相关技术和资料汇总,涉及大量javaweb基础技术诸如:Servle ...
- 从零开始学 Java - 搭建 Spring MVC 框架
没有什么比一个时代的没落更令人伤感的了 整个社会和人都在追求创新.进步.成长,没有人愿意停步不前,一个个老事物慢慢从我们生活中消失掉真的令人那么伤感么?或者说被取代?我想有些是的,但有些东西其实并不是 ...
- 【.Net架构】BIM软件架构03:Web管控平台MVC架构
一.前言 上一篇讲述的是将BIM平台后台架构CoreService.sln,该解决方案主要作用是对管控平台的核心业务进行封装,然后让前端的ApiController去调用该解决方案中的对 ...
- MAC OS X El CAPITAN 搭建SPRING MVC (1)- 目录、包名、创建web.xml
一. 下载STS(Spring Tool Suite) 官方地址:http://spring.io/tools/sts 下载spring tool suite for mac 最新版本.这个IDE是很 ...
- Android 四大组件 与 MVC 架构模式
作为一个刚从JAVA转过来的Android程序员总会思考android MVC是什么样的? 首先,我们必须得说Android追寻着MVC架构,那就得先说一下MVC是个啥东西! 总体而来说MVC不能说是 ...
- MVC架构模式分析与设计(一)---简单的mvc架构
首先 我要感谢慕课网的老师提供视频资料 http://www.imooc.com/learn/69 下面我来进行笔记 我们制作一个简单的mvc架构 制作第一个控制器 testController.cl ...
- IntelliMVCCode智能MVC架构的代码助手使用方法
智能代码生成工具,快速帮助开发者提升开发速度,通过工具自动生成MVC架构的大量源代码,节省更多的开发时间. 工具使用的框架:.net4.0,通过工具连接到数据库自动提取数据表或视图中的结构,生成对应的 ...
- 从MVC框架看MVC架构的设计
尽管MVC早已不是什么新鲜话题了,但是从近些年一些优秀MVC框架的设计上,我们还是会发现MVC在架构设计上的一些新亮点.本文将对传统MVC架构中的一些弊病进行解读,了解一些优秀MVC框架是如何化解这些 ...
随机推荐
- 天气类API调用的代码示例合集:全国天气预报、实时空气质量数据查询、PM2.5空气质量指数等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 全国天气预报:数据来自国家气象局,可根据地名.经纬度GPS.IP查 ...
- Day5模块-shutil模块
参考博客:http://www.cnblogs.com/wupeiqi/articles/4963027.html shutil模块是高级的文件.文件夹.压缩处理的模块.比如文件的copy.压缩等. ...
- (1)常见O(n^2)排序算法解析
一.选择排序 1.原始数组 2.遍历数组找到最小值索引,并将最小值索引与当前遍历索引位置互换 3.确定最小位置值,进行下一次遍历 4.java代码实现 /** * author:sam * date: ...
- 类似fabric主机管理demo
类似于fabric的主机管理系统 可以批量对主机进行操作 批量上传文件 批量下载文件 批量执行命令 demo代码 #!/usr/bin/env python # -*- coding:utf-8 -* ...
- caffe+CPU︱虚拟机+Ubuntu16.04+CPU+caffe安装笔记
由于本机是window10系统,所以想尝试caffe就在自己电脑上整了一个虚拟机(详情可见:win10系统搭建虚拟机:VMware Workstation Player 12环境+Ubuntu Kyl ...
- Jenkins+Gradle实现android开发持续集成、打包
Jenkins简介 Jenkins 是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从繁杂的集成中解脱出来,专注于更为重要的业务逻辑实现上.同时 Jenkins 能实施监控集成中存在的错误, ...
- UBOOT添加命令的执行流程
BootLoader(引导装载程序)是嵌入式系统软件开发的第一个环节,它把操作系统和硬件平台衔接在一起,对于嵌入式系统的后续软件开发十分重要,在整个开发中也占有相当大的比例.U-BOOT是当前比较流行 ...
- 不解,排名靠前那么多的人为什么抄袭我的activit博文??
刚才也是无意搜了下自己的最近发表的activiti系列博文,无意中发现居然在别人的csdn博客中也成了原创. ......
- hi3531 SDK已编译文件系统制作jffs2文件系统镜像并解决问题 .
一, 安装SDK 1.Hi3531 SDK包位置 在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx. ...
- 草料Chrome浏览器插件,让二维码更好用
安装插件草料chrome插件,是专为chrome核心的浏览器开发的一个二维码应用增强工具插件. 自动将地址栏链接生成二维码 以谷歌原生的chrome浏览器为例,插件安装成功后会在浏览器地址栏旁边出现一 ...