最近开始学习java web开发,记录一下学习的过程。
主要分为三个步骤:
1.基础:java、Mysql入门学习。
2.中级:html、css、javascipt、servlet、jsp入门学习,推荐韩顺平相关视频,w3cshool在线教程 一个很好的查找手册。
3.高级:Struts2、Hibernate、Spring分开学习到SSH简单框架搭建。
为什么要集成开发:为了让三个框架优点结合,开发便捷,减少开发成本,集成后系统分为3层,表示层、业务层、持久层。
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录
basedir=D:\mysql-5.6.23-win32
# 设置mysql数据库的数据的存放目录
datadir=D:\mysql-5.6.23-win32\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
以管理员身份打开cmd窗口后,将目录切换到你解压文件的bin目录,我的目录是图里面那个,你的话,要以你自己的目录为准。再输入mysqld install回车运行就行了,注意是是mysqld,不是mysql出现安装成功就ok了。我由于已经安装了,所以结果就是这个了
8.打开MySQL
还是将目录切换到D:\mysql\mysql-x.x.xx-winx64\bin(x.xx.xxx是什么根据你自己的版本来吧)输入mysql -uroot -p ,默认是没有密码的。回车进入,当然我的已经设置密码了,所以要输入密码才能进。有密码的话,可以mysql -uroot -p密码,也是可以是mysql -uroot -p 回车输入密码,推荐第二种,原因,你动手之后就知道了。
设置密码的方法:mysqladmin -u root -p password 密码。
退出exit 就行了。记住直接关闭cmd窗口是没有退出的,要输入exit才会退出啊。
9.虽然打开mysql 了,但每次打开mysql 都要输入那么多指令切换目录太麻烦了。
右键我的电脑->属性->高级系统设置->环境变量->path->编辑,将你的mysql软件下的bin目录的全路径放里面。建议放在最前面,最后在那个目录的路径后面加个英文的分号(;)保存就行了。如D:\mysql\mysql-x.x.xx-winx64\bin;
原理简单的说环境变量里面的path路径这东西,就是cmd系统的查找目录路径。你输入一个指令系统是在当前目录和系统环境变量path里面的路径全部查找一边,找到第一个为准,找不到就报错。所以我们要不每次都切换cmd目录,要不就设置了,以后就不需要再切换cmd路径了。
10.cmd->mysql -uroot -p ->回车输入密码->show databases;查找数据库->use 数据库名;切换数据库目录->show tables;查找表->sql查询工作select * from 表名->exit退出
①点击File→New→Web Project 新建一个Web工程,在Project Name中输入项目名ssh1,在J2EE Specification Level中选择Java EE 6.0,然后点击Finish。
Driver name填写链接数据库的名称(这个可由自己喜好填写,建议最好和所做项目名称相关便于使用时查找)
Connection URL用于填写连接要使用mysql数据库的地址(jdbc:mysql://<hostname>[<:3306>]/<dbname>)可改为(jdbc:mysql://localhost:3306/am),其中localhost表示的是连接本地数据库的意思,3306是表示连接mysql数据库的端口号(不同的数据库端口号也不相同),
User name 填写数据库用户名mysql默认的是root
Password填写访问mysql数据库时的你所设置的访问密码。
点击Add JARs添加myeclipse连接mysql数据库的驱动文件(存放驱动的文件最好是英文目录,在测试时确定mysql数据库已经打开,否则测试不会成功),在这里添加的是mysql-connector-java-5.6-bin.jar(一定选好对应的jar包,否则连接失败)
<pre name="code" class="plain"> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- 表现层:多个JSP页面
- MVC层:使用Struts2框架
- 业务逻辑层:使用业务逻辑组件构成
- DAO层:由DAO组件构成
- Hibernate层:使用Hibernate3框架
- 数据库层:使用MySQL数据库来储存系统数据。
字段名 | 字段含义 | 数据类型 | 是否主键 |
id | 用户标识 | int(10) | 是 |
name | 用户姓名 | varchar(10) | 否 |
password | 用户密码 | varchar(10) | 否 |
type | 用户类型 | varchar(10) | 否 |
user.java
package com.lmz.entity;
public class User {
private int id;//用户标识
private String name;//用户名
private String password;//密码
private String type;//类型
public User()//默认构造函数
{
}
//包含全部属性的构造函数
public User(int id, String name, String password, String type) {
this.id = id;
this.name = name;
this.password = password;
this.type = type;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
2.创建映射文件
user类的User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.lmz.entity.User" table="user">
<id name="id" column="id" type="java.lang.Integer">
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String" column="name" >
</property>
<property name="password" type="java.lang.String" column="password" >
</property>
<property name="type" type="java.lang.String" column="type" >
</property>
</class>
</hibernate-mapping>
1.创建DAO接口
package com.lmz.dao;
import java.util.List;
import com.lmz.entity.User;
public interface UserDAO {
void save(User user);
User getUser(String name);
void delete(int id);
void update(User user);
User findById(int id);
List<User> findALL();
}
2.创建DAO实现类
package com.lmz.dao;
import java.util.List;
import com.lmz.entity.User;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {
public void save(User user) {
this.getHibernateTemplate().save(user);
}
public User getUser(String name) {
String hsql="from User u where u.name='"+name+"'";
User result=(User)((Query) this.getHibernateTemplate().find
(hsql)).uniqueResult();
return result;
}
public void delete(int id) {
this.getHibernateTemplate().delete(findById(id));
}
public void update(User user) {
this.getHibernateTemplate().update(user);
}
public User findById(int id) {
User user=(User)this.getHibernateTemplate().get(User.class,id);
return user;
}
@SuppressWarnings("unchecked")
public List<User> findALL() {
String queryString="from User";
List<User> list=this.getHibernateTemplate().find(queryString);
return list;
}
}
四、业务逻辑层设计
1.创建业务逻辑组件接口
package com.lmz.service;
import java.util.List;
import com.lmz.entity.User;
public interface UserService {
void saveUser(User user);
User getUser(String name);
void deleteUser(int id);
void updateUser(User user);
User findUserById(int id);
List<User> findALL();
}
2.创建业务逻辑实现类
package com.lmz.service;
import java.util.List;
import com.lmz.dao.UserDAO;
import com.lmz.entity.User;
public class UserServiceImpl implements UserService {
private UserDAO userDAO;
public UserDAO getUserDAO() {
return userDAO;
}
//提供Userdao对象注入通道
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
//添加用户
public void saveUser(User user) {
if(userDAO.findById(user.getId())==null)
userDAO.save(user);
}
//按用户名查找用户
public User getUser(String name) {
return userDAO.getUser(name);
}
//删除用户
public void deleteUser(int id) {
if(userDAO.findById(id)!=null)
userDAO.delete(id);
}
//更新用户
public void updateUser(User user) {
if(userDAO.findById(user.getId())!=null)
userDAO.update(user);
}
//按id号查找用户
public User findUserById(int id) {
return userDAO.findById(id);
}
//查找全部用户
public List<User> findALL() {
return userDAO.findALL();
}
}
五、用户登录设计
1.创建用户登录Action
package com.lmz.action;
import java.util.Iterator;
import java.util.List;
import com.lmz.service.UserService;
import com.lmz.entity.User;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private UserService userService;
String username;
String password;
String usertype;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsertype() {
return usertype;
}
public void setUsertype(String usertype) {
this.usertype = usertype;
}
@Override
public String execute () throws Exception
{
List<User> list=(List<User>) userService.findALL();
User u=new User();
Iterator<User> it=list.iterator();
while(it.hasNext())
{
u=(User)it.next();
if(username.trim().equals(u.getName())&&password.trim().equals(u.getPassword())&&
usertype.trim().equals(u.getType()))
return "success";
else return "failer";
}
String page="failer";
return page;
}
}
2.用户登录界面 login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户登录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<s:form action="tt" method="post">
<s:textfield name="username" label="用户名"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:textfield name="usertype" label="类型"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
六、查询所有用户信息
1.创建查询Action
package com.lmz.action;
import java.util.List;
import org.apache.struts2.ServletActionContext;
import com.lmz.entity.User;
import com.lmz.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserQueryAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 9055821854498300493L;
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String execute()
{
List<User> userlist=userService.findALL();
ServletActionContext.getRequest().setAttribute("userlist", userlist);
return "success";
}
}
2.创建query.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>显示用户信息</title>
</head>
<body>
<center>
<h1>用户信息</h1>
<table border="1" width="400">
<tr>
<th>用户ID</th>
<th>用户名</th>
<th>密码</th>
<th>用户类型</th>
<th>是否删除</th>
<th>是否修改</th>
</tr>
<s:iterator value="#request.userlist" id="st">
<tr>
<td align="center"><s:property value="#st.id"/></td>
<td align="center"><s:property value="#st.name"/></td>
<td align="center"><s:property value="#st.password"/></td>
<td align="center"><s:property value="#st.type"/></td>
<td><a href="userdelete.action?id=<s:property value='#st.id'/>">删除</a></td>
<td><a href="update.jsp?id=<s:property value='#st.id'/>">更新</a></td>
</tr>
</s:iterator>
</table>
<br>
<a href="save.jsp">添加用户</a>
</center>
</body>
</html>
六、添加用户信息
1.新建UserAction
package com.lmz.action;
import com.lmz.entity.User;
import com.lmz.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 5015042759666091959L;
private UserService userService;
private User user;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute()
{
User u=new User();
u.setName(user.getName());
u.setPassword(user.getPassword());
u.setType(user.getType());
userService.saveUser(u);
return "success";
}
}
2.添加用户界面save.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>添加用户</title>
</head>
<body>
<center>
<s:form action="fpq" method="post">
<tr>
<td colspan="2" align="center">
<h1><s:text name="欢迎注册"/></h1><br/>
<s:property value="exception.message"/>
</td>
</tr>
<s:textfield name="user.name" key="用户名"
tooltip="Enter your name!" required="ture">
</s:textfield>
<s:textfield name="user.password" key="密码"
tooltip="Enter your password!" required="ture">
</s:textfield>
<s:textfield name="user.type" key="类型"
tooltip="Enter your type!" required="ture">
</s:textfield>
<s:submit value="提交"></s:submit>
<s:set/>
</s:form>
</center>
</body>
</html>
七、删除用户信息
1.创建UserDeleteAction,删除指定的id用户
package com.lmz.action;
import com.lmz.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserDeleteAction extends ActionSupport{
private static final long serialVersionUID = 8946391208476631350L;
private UserService userService;
private int id;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String execute()
{
userService.deleteUser(id);
return "success";
}
}
八、更新用户信息
1.创建更新用户Action
package com.lmz.action;
import com.lmz.entity.User;
import com.lmz.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserUpdateAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 5133823259070217467L;
private UserService userService;
private User user;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute()
{
if(userService.findUserById(user.getId())!=null)
{
setUser(user);
userService.updateUser(user);
return "success";
}
addActionMessage(getText("error.message.not.exist"));
return "input";
}
}
2.新建修改用户信息页面update.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>修改用户信息</title>
</head>
<body>
<center>
<s:form action="change" method="post">
<tr>
<td colspan="2" align="center">
<h1><s:text name="修改用户信息"/></h1><br/>
<s:actionerror/>
</td>
</tr>
<s:textfield name="user.id" key="用户ID"
required="ture">
</s:textfield>
<s:textfield name="user.name" key="用户名"
required="ture">
</s:textfield>
<s:password name="user.password" key="密码"
required="ture">
</s:password>
<s:textfield name="user.type" key="类型"
required="ture">
</s:textfield>
<s:submit value="提交"></s:submit>
<s:reset value="重置"></s:reset>
<s:set/>
</s:form>
</center>
</body>
</html>
九、创建success.jsp、error.jsp
1.success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'success.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my success page. <br>
</body>
</html>
2.error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'error.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my error page. <br>
</body>
</html>
十、配置web.xml、applicationContext.xml、struts.xml
1.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
2.applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url" value="jdbc:mysql://localhost:3306/am"></property>
<property name="username" value="root"></property>
<property name="password" value="china1992"></property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
<!-- 制定hibernate映射文件路径 -->
<property name="mappingResources">
<list>
<value>com/lmz/entity/User.hbm.xml</value>
</list>
</property>
</bean>
<bean id="userDAO" class="com.lmz.dao.UserDAOImpl" scope="singleton">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean id="userService" class="com.lmz.service.UserServiceImpl">
<property name="userDAO" ref="userDAO"></property> <!--注入DAO组件 -->
</bean>
<bean id="loginAction" class="com.lmz.action.LoginAction">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userQueryAction" class="com.lmz.action.UserQueryAction" >
<property name="userService" ref="userService"></property>
</bean>
<bean id="lmz" class="com.lmz.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userDeleteAction" class="com.lmz.action.UserDeleteAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<bean id="update" class="com.lmz.action.UserUpdateAction" >
<property name="userService" ref="userService"></property>
</bean>
</beans>
3.struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- <constant name="struts.objectFactory" value="spring"/> -->
<package name="default" extends="struts-default">
<action name="tt" class="loginAction">
<result name="success">/success.jsp</result>
<result name="failer">/error.jsp</result>
</action>
<action name="userquery" class="userQueryAction">
<result name="success">/query.jsp</result>
</action>
<action name="fpq" class="lmz">
<result name="success" type="redirect" >/userquery.action</result>
</action>
<action name="userdelete" class="userDeleteAction">
<result name="success" type="redirect" >/userquery.action</result>
</action>
<action name="change" class="update">
<result name="success" type="redirect" >/userquery.action</result>
<result name="input" >/update.jsp</result>
</action>
</package>
</struts>
创建好的项目如下图所示
十一、测试用户管理系统
1.测试用户登录系统
在浏览器,输入http://localhost:8080/lmzManagement/
输入当前数据库已有的jack或rose用户,单击“提交”转到success.jsp显示登录成功,否则转向error.jsp,提示错误。
注意在下方控制台中显示mysql语句
Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.password as password0_, user0_.type as type0_ from user user0_
十二、测试用户信息界面
在浏览器输入http://localhost:8080/lmzManagement/userquery
十三、测试添加用户
1.点击上一步中的“添加用户”超链接,跳转到添加用户信息,在页面中输入用户信息,单击“提交”进行添加。
2.用户添加完毕后,页面转到用户信息界面,新增了leo用户,添加成功。
十四、测试删除用户
单击上一步leo用户的“删除”超链接,删除leo用户
十五、测试更新用户
1.在用户信息界面中,单击jack的“更新”超链接,完成对jack的信息更改。
这里我们更改了jack的类型"jack"为"帅哥”
2.单击“提交”按钮,页面再次返回用户信息界面,此时页面中的jack的用户类型变为“帅哥”。
工程下载:http://download.csdn.net/detail/am45337908/8596091
总结:
1.配置LoginAction的bean时,id不能为login,否则浏览器报出500错误(应该是关键字冲突)。
2.MySQL connector jar包应选择与使用MySQL数据库版本相同或者接近,否则不能连接数据库,service不能实例化。
SSH框架实现了一个简单的用户管理系统,在调试过程,遇到了很多错误,经验总结就是要一步一步来调试,不要想着一步就能登天。也突然想起了初一的莫顿·亨特的一篇文章《走一步,再走一步》的一段话,”我曾屡次发现,每当我感到前途茫茫而灰心丧气时,只要记起很久以前我在那座小悬崖上所学到的经验,我便能应付一切。我提醒自己,不要想着远在下面的岩石,而要着眼于那最初的一小步,走了这一步再走下一步,直到抵达我所要到的地方。这时,我便可以惊奇而自豪地回头看看,自己所走过的路程是多么漫长。” 编程、学习如此,人生亦如此,与君共勉。