java使用sql之使用for update锁定表

一:

1>首先for update是对表的行进行锁定。锁定就好比我们学java Thread那一章时,为某个线程的run()枷锁,当实例化出来多个线程时,它必须一个线程全部执行完后,释放锁其他线程才有机会运行。本文for update功能上一样,就是为一个select语句枷锁,这样在对这个表进行update ,delete时就会处于等待状态,等待selec执行commit或rollback(相当于线程释放锁)后,才可以对表进行更改或删除。

怎样看效果呢?1:首先在“运行”–>cmd–>连接数据库 执行select * from emp for update

2 :然后在打开另一个窗口(就相当于创建了两个用户):“运行”–>cmd–>连接数据库  执行update emp set sal=100;你会发现它不执行了。

2>那马for update与for update of 有神马区别呢?

1.select * from Table1 for update 锁定表的所有行,只能读不能写

2  select * from Table1 where id = 1 for update 只锁定id=1的行

3  select * from Table1 a join Table2 b on a.id=b.id for update 锁定两个表的所有记录

4 select * from Table1 a join Table2 b on a.id=b.id where a.id = 10 for update 锁定两个表的中满足条件的行

5. select * from Table1 a join Table2 b on a.id=b.id where a.id = 10 for update of a.id 只锁定Table1中满足条件的行

for update 是把所有的表都锁点 for update of 根据of 后表的条件锁定相对应的表

3>关于oracle:select…for update of columns

按照1>步骤执行1:select * from emp for update of sal在另一个窗口中执:2:update emp set job=’clerk’ where empno=10;按照2>的的思维我们可能认:“1”只锁定了emp表的sal列,其实不然当运行“2”时,我们发现它任然不执行,所以for update of columns 是锁定的与sal相关的行。那么for update 与for update of 有神吗区别呢?区别在于多表连接时;

例如:

按照1>分别执行 select ename,dname from emp,dept where emp.deptno=dept.deptno for update;

另一窗口执行:update dept set dname=’haha’where deptno=10;我们发现dept表不能更改

当我们在 select ename,dname from emp,dept where emp.deptno=dept.deptno for update of sal;时

update dept set dname=’haha’where deptno=10;可以在执行了。

由此我们可以综结出:for update of columns 用在多表连接锁定时,可以指定要锁定的是哪几张表,而如果表中的列没有在for update of 后面出现的话,就意味着这张表其实并没有被锁定,其他用户是可以对这些表的数据进行update操作的。这种情况经常会出现在用户对带有连接查询的视图进行操作场景下。用户只锁定相关表的数据,其他用户仍然可以对视图中其他原始表的数据来进行操作。

4>关于nowait与wait

SELECT … FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];
1:其中:

OF 子句用于指定即将更新的列,即锁定行上的特定列。

NOWAIT不进行等待,如果这条语句的锁没被释放,则会直接报出:系统资源正忙
WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。
“使用FOR UPDATE WAIT”子句的优点如下:
1防止无限期地等待被锁定的行;
2允许应用程序中对锁的等待时间进行更多的控制。
3对于交互式应用程序非常有用,因为这些用户不能等待不确定
4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告 :

2:现在执行如下操作:

在plsql develope中打开两个sql窗口, 在1窗口中运行sql
select * from t where a=’1′ for update;
在2窗口中运行sql1
1. select * from t where a=’1′; 这一点问题也没有,因为行级锁不会影响纯粹的select语句
再运行sql2
2. select * from t where a=’1′ for update; 则这一句sql在执行时,永远处于等待状态除非窗口1中sql 被提交或回滚。
如何才能让sql2不等待或等待指定的时间呢? 我们再运行sql3
3. select * from t where a=’1′ for update nowait; 则在执行此sql时,直接报资源忙的异常。
若执行 select * from t where a=’1′ for update wait 6; 则在等待6秒后,报 资源忙的异常。 如果我们执行 sql4
4. select * from t where a=’1′ for update nowait skip Locked; 则执行sql时,即不等待,也不报资源 忙异常。
现在我们看看执行如下操作将会发生什么呢?
在窗口1中执行:
select * from t where rownum<=3 nowait skip Locked;
在窗口2中执行:
select * from t where rownum<=6 nowait skip Locked;
select for update 也就如此了吧,insert、update、delete操作默认加行级锁,其原理和操作与select for update并无两样。
select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定.

二:

1:

如果你想删除或者更新被Select For Update引用的记录,你可以使用Where Current Of语句

 

[sql]
  1. DECLARE
  2.   CURSOR CUR_NAME IS
  3.     SELECT * FROM EMP WHERE deptno=10 FOR UPDATE OF sal;
  4. BEGIN
  5.   FOR REC IN CUR_NAME LOOP
  6.     UPDATE EMP SET sal =100 ;
  7.   END LOOP;
  8. END;

上述pl/sql执行过之后我们发现emp表中所有的sal列数据都被更改,此时我们只想更改跟游标对应的行,所以我们又到where current of执行游标遍历时的当前行就好像for(int i=0;i++;i<10){}where current of与“i”的功能相似。所以当我们想执行游标影响的行时,上我们可以把上面pl/sql快改为:

 

[sql]
  1. DECLARE
  2.   CURSOR CUR_NAME IS
  3.     SELECT JOB FROM EMP WHERE deptno=10 FOR UPDATE OF sal;
  4. BEGIN
  5.   FOR REC IN CUR_NAME LOOP
  6.     UPDATE EMP SET sal =100 WHERE CURRENT OF CUR_NAME;
  7.   END LOOP;
  8. END;

Struts1开发流程描述

我们在这篇文章将会一步一步的讲解Struts的应用,以这样的形式打开Struts一道道神秘的大门,通过这样的过程,相信也能激起你在应用开发中如何应用Struts的灵感。如果你对Struts的一些术语不是很清楚的话,可以参考本系列前一篇对Struts作大体介绍的文章。
再次重复一遍,本文需要读者有如下几方面的知识和经验:JSP,Servlets,自定义标签库(CustomTaglibraries)和XML。此外,在本文中,我还会用到Jakarta项目组其他一些好东东,比如Tomcat(实现Servlet和JSP官方标准的Servlet容器,通俗的讲就是一个JSP的Web啦)和Ant(基于Java的自动编译发布工具,这可是好东东啊)。
作为一名一直使用前沿技术开发了诸多应用的技术人员,我一直坚信掌握新技术,理解该技术开发的逻辑是至关重要的。但这往往就是陷住我们学习步伐的泥潭,正因如此,我打算将利用Struts开发的一套完整流程作为我们教学的案例。该流程的这个案例可谓“麻雀虽小、五脏据全”,你完全可以将这个流程应用到你手头那些复杂庞大的项目中,至少在我们的大项目中应用这个流程效果不错。
有开发复杂商业应用的开发人员都知道,客户的需求总是在不停变幻,所以如果有一套规范的开发流程来遵循,当客户提出新的需求时,我们至少可以明确哪些“无理”需求其实是合理可行的。好,接下里我将在我的这个例子中向各位展示和应用整个流程。
本文中的示例代码是StrutsSample应用中的一部分,包括build.xml的完整代码可以到此处http://www.onjava.com/onjava/2001/10/31/examples/StrutsPartII.jar下载。
Struts开发过程
从Struts发布的版本号可以看出,Struts是个新玩意,她有好几个部分组成,明智的你如果搞清楚了何时该开发完成合适的部分,那将会更好的利用我们的开发时间。从我所开发的几个利用Struts应用中,我大致总结出如下这个比较有效的开发步骤:
1,明确应用需求;
2,由用户输入和获取数据的角度出发,明确和设计出每一个用户界面;
3,确定用户界面的进入路径;
4,由应用逻辑确定动作映射表;
5,由设计完成的用户界面开发其所用到的类和应用函数;
6,由用户界面中的数据开发ActionForm和相应的数据校验方法;
7,ActionMapping中将会被调用相应的Action或转到相应的JSP页面,这一步我们先开发这些Action;
8,开发商业应用逻辑,就是相应的JavaBean、EJB或其他东东;
9,开发由ActionMapping定义的系统工作流程完成对应的JSP页面;
10,完成系统:struts-config.xml和web.xml;
11,编译/测试/发布。
明确应用需求
开发任何应用系统的第一步就是收集用户需求。不管一个用户逻辑初看上去多么合理,但总有可能在开发时才发现它比看上去要难得多。所以,建议拟一份明确的用户需求列表,这不只是出于开发的目的,还能通过该表分析用户需求以确定哪些地方可能需要花更多的精力。
在我们这个StrutsSample项目中,应用需求就是:
作为一个展示Struts框架应用的完整例子,本示例完成的功能是用户登录。目的只为明确Struts的应用,本示例将不会涉及到一般复杂应用系统中可能应用的安全、、EJB开发等等相关技术。
设计用户界面
这个应用中,包括如下三个用户界面:
1)登录界面,用于用户名和密码输入;
2)当登录用户为合法用户时的欢迎界面;
3)当登录失败时的错误提示界面。
确定用户界面的进入路径
1)登录界面作为这个应用的默认页面;
2)欢迎界面只有当成功登录后才能进入;
3)任何可能发生错误的页面能可以进入错误提示界面;
由应用逻辑确定ActionMapping
ActionMapping为整个应用确定的“线路图”,在配置文件struts-config.xml对ActionMapping进行定义,通过转发请求(forward)来理顺应用的处理流程,确定应用中每个用户请求对应的动作。
通常我们在开发过程中就逐步确定了ActionMapping所需的,开发代码的过程就是在由草稿开始一步步完善struts-config.xml的过程。当Action类处理完用户请求后,其返回的的forward就是在ActionMapping中定义的一个。一个Action返回的forward完全有多种可能,尽管一个Action一般只定义其相关的几个forward。那么,如果有多个Action都可能返回的同一个forward,那么就可以将其定义为全局转发(globalforward)。这类似于C中的头文件中全局变量,如果在struts-config.xml描述中,某一个forward并不是在当前Action描述中定义的而是全局定义的,那么这个全局的将起作用,同样,一个Action中当前定义的forward将覆盖全局定义。在我们所给的这个简单实例中,我们定义了全局forward――“error”,当某Action返回的forward是“error”这个映射,那么Errorpage.jsp页面将会显示给用户,尽管当前Action并没有对其定义。
我们继续不断的开发,项目日渐完善,项目相关的配置文件也会越来越详细。在下面的例子中,我们将以StrutsSample中用到的struts-confug.xml文件为例,学习globalforward和一个Action中相关映射的定义。下面定义了一个名为“login”的Action,其为com.oreilly.actions.LoginAction的实例,当Action处理用户登录成功后将一个名为”success”的forward返回,用户也就会看到Welcome.jsp页面,如果登录失败,Action将返回对应的forward以再显示Login.jsp给用户,而如果处理过程中发生其他错误,Action将返回全局定义的forward――“error”,用户也就会看到错误提示页面Errorpage.jsp。
元素的相关属性–>
以下只列出常用属性,其他请参考org.apache.struts.action.ActionMapping的相关文档
path-当前Action对应的用户请求URI路径
type-实现当前Action的Javaclass的完整名字
name-当前Action中用到的ActionForm的名字,其具体在配置文件其他地方另有详细定义
unknown-如果将该属性设置为true,那么就是声明这个Action将处理整个应用中所有未找到相应处理Action的请求,当然,一个应用系统中也只会有一个Action的unknown属性可以设为true
scope-Action中所用到的ActionForm的生存期,可以为“request”或“session”,随着生存期的设置,该Action也会在相应的时间被创建
input-该Action中相关ActionForm获取用户输入的输入页面,当将ActionForm设为自动验证输入数据,发现不合法数据返回错误时,将返回该页面
validate-如果本属性为true则在Action动作之前其对应的ActionForm的validate方法会自动被调用,一般用以验证用户输入的数据
forward元素-定义当前Action相关的ActionForward
–>
type=”com.oreilly.actions.LoginAction”
name=”loginForm”
scope=”request”
input=”/Login.jsp”>
在前一篇文章中,我们曾说过,struts-config.xml就是MVC模式的的Controller。在确定struts-config.xml中的配置时,应该多花些时间精力在上面,以保证每一个Action定义及其相关定义是符合应用的需求的。如果在项目开始没有详细的设计其定义,当将所有代码和配置集成到一起的时候,我们将不可避免的将各部分的代码和配置完全重新组织一遍。
我们当前的例子StrusSample因为只是处理用户登录,所以只需要一个Action。一个应用系统中所要用到的Action的多少完全依应用的大小而定。一旦整套Action的映射完全的定义出来后,我们就可以一个一个开发其具体实现的Action和ActionForm类,并逐渐将完成的部分一点一点集成起来。
由设计完成的用户界面开发其所用到的类和应用函数
所有ActionForm的实现类都是org.apache.struts.ActionForm的子类。一个ActionForm是与页面上的输入表单相关联的,而且ActionForm的实现还可以对用户输入数据的合法性进行验证。作为一个JavaBean,ActionForm有Set和Get方法,当一个页面中表单被提交时,系统将自动调用Set方法将数据放入ActionForm中,而Get方法将为在Action中操作这些数据所提供。一般来说,处理表单中的所有数据,并进行合法性验证都完全可以交由ActionForm来完成。在应用中,就我个人而言,倾向于将ActionForm和Action划分到不同的包中,因为当一个页面中要用到几对ActionFrom和Action时,都放在一个包内会混淆的。

spring之面向切面编程(AOP)PointCut匹配法则说明

Pointcut 是指那些方法需要被执行”AOP”,是由”Pointcut Expression”来描述的.
Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合.
args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation
其中execution 是用的最多的,其格式为:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
returning type pattern,name pattern, and parameters pattern是必须的.
ret-type-pattern:可以为*表示任何返回值,全路径的类名等.
name-pattern:指定方法名,*代表所以,set*,代表以set开头的所有方法.
parameters pattern:指定方法参数(声明的类型),(..)代表所有参数,(*)代表一个参数,(*,String)代表第一个参数为任何值,第二个为String类型.
举例说明:
任意公共方法的执行:
execution(public * *(..))
任何一个以“set”开始的方法的执行:
execution(* set*(..))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
定义在service包和所有子包里的任意类的任意方法的执行:
execution(* com.xyz.service..*.*(..))
定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))”)
***> 最靠近(..)的为方法名,靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..))

pointcutexp包里的任意类.
within(com.test.spring.aop.pointcutexp.*)
pointcutexp包和所有子包里的任意类.
within(com.test.spring.aop.pointcutexp..*)
实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类.
this(com.test.spring.aop.pointcutexp.Intf)
***> 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型.

带有@Transactional标注的所有类的任意方法.
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)
带有@Transactional标注的任意方法.
@annotation(org.springframework.transaction.annotation.Transactional)
***> @within和@target针对类的注解,@annotation是针对方法的注解

参数带有@Transactional标注的方法.
@args(org.springframework.transaction.annotation.Transactional)
参数为String类型(运行是决定)的方法.
args(String)
Pointcut 可以通过Java注解和XML两种方式配置,如下所示:

  1. <aop:config>
  2.     <aop:aspectrefaop:aspectref=”aspectDef”>
  3.         <aop:pointcutidaop:pointcutid=”pointcut1″expression=”execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))”/>
  4.         <aop:before pointcut-ref=”pointcut1″ method=”beforeAdvice” />
  5.     </aop:aspect>
  6. </aop:config>
  7. @Component
  8. @Aspect
  9. public class AspectDef {
  10.     //@Pointcut(“execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))”)
  11.     //@Pointcut(“within(com.test.spring.aop.pointcutexp..*)”)
  12.     //@Pointcut(“this(com.test.spring.aop.pointcutexp.Intf)”)
  13.     //@Pointcut(“target(com.test.spring.aop.pointcutexp.Intf)”)
  14.     //@Pointcut(“@within(org.springframework.transaction.annotation.Transactional)”)
  15.     //@Pointcut(“@annotation(org.springframework.transaction.annotation.Transactional)”)
  16.     @Pointcut(“args(String)”)
  17.     public void pointcut1() {
  18.     }
  19.     @Before(value = “pointcut1()”)
  20.     public void beforeAdvice() {
  21.         System.out.println(“pointcut1 @Before…”);
  22.     }

java_memcached-release 关键类及方法整理

java_memcached-release 关键类及方法整理说明如下。
SockIOPool
  这个类用来创建管理客户端和服务器通讯连接池,客户端主要的工作包括数据通讯、服务器定位、hash 码生成等都是由这个类完成的。
1.public static SockIOPool getInstance()
  获得连接池的单态方法。这个方法有一个重载方法getInstance( String poolName ),每个poolName 只构造一个SockIOPool 实例。缺省构造的poolName 是default。如果在客户端配置多个memcached 服务,一定要显式声明poolName。
2.public void setServers( String[] servers )
  设置连接池可用的cache 服务器列表,server 的构成形式是IP:PORT(如:127.0.0.1:11211)
3.public void setWeights( Integer[] weights )
  设置连接池可用cache 服务器的权重,和server 数组的位置一一对应其实现方法是通过根据每个权重在连接池的bucket 中放置同样数目的server(如下代码所示),因此所有权重的最大公约数应该是1,不然会引起bucket 资源的浪费。
4.public void setInitConn( int initConn )
  设置开始时每个cache 服务器的可用连接数
5.public void setMinConn( int minConn )
  设置每个服务器最少可用连接数
6.public void setMaxConn( int maxConn )
  设置每个服务器最大可用连接数
7.public void setMaxIdle( long maxIdle )
  设置可用连接池的最长等待时间
8.public void setMaintSleep( long maintSleep )
  设置连接池维护线程的睡眠时间 设置为0,维护线程不启动 维护线程主要通过log 输出socket 的运行状况,监测连接数目及空闲等待时间等参数以控制连接创建和关闭。
9.public void setNagle( boolean nagle )
  设置是否使用Nagle 算法,因为我们的通讯数据量通常都比较大(相对TCP 控制数据)而且要求响应及时,因此该值需要设置为false(默认是true)
10.public void setSocketTO( int socketTO )
  设置socket 的读取等待超时值
11.public void setSocketConnectTO( int socketConnectTO )
  设置socket 的连接等待超时值
12.public void setAliveCheck( boolean aliveCheck )
  设置连接心跳监测开关。 设为true 则每次通信都要进行连接是否有效的监测,造成通信次数倍增,加大网络负载,因此该参数应该在对HA 要求比较高的场合设为TRUE,默认状态是false。
13.public void setFailback( boolean failback )
  设置连接失败恢复开关 设置为TRUE,当宕机的服务器启动或中断的网络连接后,这个socket 连接还可继续使用,否则将不再使用,默认状态是true,建议保持默认。
14.public void setFailover( boolean failover )
  设置容错开关 设置为TRUE,当当前socket 不可用时,程序会自动查找可用连接并返回,否则返回NULL,默认状态是true,建议保持默认。
15.public void setHashingAlg( int alg )
  设置hash 算法 alg=0 使用String.hashCode()获得hash code,该方法依赖JDK,可能和其他客户端不兼容,建议不使用 alg=1 使用original 兼容hash 算法,兼容其他客户端; alg=2 使用CRC32 兼容hash 算法,兼容其他客户端,性能优于original 算法; alg=3 使用MD5 hash 算法采用前三种hash 算法的时候,查找cache 服务器使用余数方法。采用最后一种hash 算法查找cache 服务时使用consistent 方法。
16.public void initialize()
  设置完pool 参数后最后调用该方法,启动pool。
MemcachedClient
1.public void setCompressEnable( boolean compressEnable )
  设定是否压缩放入cache 中的数据 默认值是ture 如果设定该值为true,需要设定CompressThreshold
2.public void setCompressThreshold( long compressThreshold )
  设定需要压缩的cache 数据的阈值 默认值是30k
3.public void setPrimitiveAsString( boolean primitiveAsString )
  设置cache 数据的原始类型是String .默认值是false 只有在确定cache 的数据类型是string 的情况下才设为true,这样可以加快处理速度。
4.public void setDefaultEncoding( String defaultEncoding )
  当primitiveAsString 为true 时使用的编码转化格式 默认值是utf‐8 如果确认主要写入数据是中文等非ASCII 编码字符,建议采用GBK 等更短的编码格式
5.cache 数据写入操作方法
5.1.set 方法
  将数据保存到cache 服务器,如果保存成功则返回true 如果cache 服务器存在同样的key,则替换之 set 有5 个重载方法,key 和value 是必须的参数,还有过期时间,hash 码,value 是否字符串三个可选参数
5.2.add 方法
  将数据添加到cache 服务器,如果保存成功则返回true 如果cache 服务器存在同样key,则返回false add 有4 个重载方法,key 和value 是必须的参数,还有过期时间,hash 码两个可选参数
5.3.replace 方法
  将数据替换cache 服务器中相同的key,如果保存成功则返回true如果cache 服务器不存在同样key,则返回false replace 有4 个重载方法,key 和value 是必须的参数,还有过期时间,hash 码两个可选参数 建议分析key 的规律,如果呈现某种规律有序,则自己构造hash 码,提高存储效率
6.cache 数据读取操作方法
  使用get 方法从cache 服务器获取一个数据 如果写入时是压缩的或序列化的,则get的返回会自动解压缩及反序列化 get 方法有3 个重载方法,key 是必须的参数,hash 码和value是否字符串是可选参数 .

配置ant

Windows 下的安装和配置

安装步骤:

  1. 下载最新版本,ANT官方网站: http://ant.apache.org/ 下载后解压缩即可。
  2. 配置环境变量:

打开环境变量配置窗口可以通过下面步骤打开:我的电脑(Vista之后叫 计算机) –> 右键属性菜单点击 –> 高级(Vista之后是 高级系统设置) –>  点击环境变量按钮(如下图:)

image

然后在随后出现的环境变量窗口中的系统变量这里,增加下面的两个设置:

image

  • ANT_HOME:C:apache-ant-1.7.1                 (这里为你自己解压缩的目录)
  • PATH:%ANT_HOME%bin                          (这个设置是为了方便在dos环境下操作)

 

完成上述步骤,就安装完毕。

 

查看是否安装成功。

在dos窗口中输入命令ant,若出现结果:
Buildfile:build.xml does not exist!
Build failed
说明ant安装成功!因为ant默认运行build.xml文件,这个文件需要我们建立。

 

一个简单的使用ANT的例子

在 D 盘根目录下新建一个 build.xml 文件,文件的内容如下:

<?xml version="1.0" encoding="GBK"?>
<project name="测试脚本" default="copyfile" basedir="." >
   <target name="copyfile">
      <copy file="d:/a.txt" todir="e:/Temp" overwrite="true" />
   </target>
</project>

在 D 盘根目录下新建一个 a.txt 文件,内容随便。

进入DOS,依次执行:

d:
ant

如同下面的截图:

image

执行完毕后,我们会在 e:/Temp 目录下看到 a.txt 文件,跟D盘根目录下的完全一样,即Copy成功。

 

 

如果中间提示类似如下错误:

Unable to locate tools.jar. Expected to find it in C:Program FilesJavajre6libtools.jar

这是因为JDK 的安装有问题或者是 JAVA_HOME 环境变量没有设置或者设置有问题, jre下肯定没tools.jar。

Byobu Terminal

装上ubuntu12.04 lts之后,查看安装的软件,发现一个好东东,叫byobu terminal,以前没用过,虽然别的终端用的也不一定熟,但是看了下简介貌似比ubuntu自带的那个terminal好用的样子。

简介保存下来,回头继续看。

—————————————————

screen 是 linux 下一个终端里实现多 session 的工具, byobu 是 ubuntu 下 screen 的一个封装 (wrapper)

byobu 其实就是利用 screen 强大的配置功能搞了很多有用的配置项. 它最大的特性一个是 key-binding, 将新窗口, 窗口切换, 重命名等操作绑定到了 F2~F9等键, 另外, F12键可以锁定终端, 输入登陆密码后才解锁. 另一个特性是屏幕底部显示一系列信息 (status), 有 cpu, 内存, 时间 等信息。

默认的快捷键主要有: F2: new window , F3/F4: switch , F5 reload, F6: Detach, F7: 回滚模式, F8: rename, F12:lockscreen

如果你用的是 putty, 它默认的按键绑定跟 byobu 的冲突. 在 putty的 Terminal => Keyboard 配置里选 “Xterm R6″ 后保存, 上面的快捷键就都可以用了

它默认的配置最底部左边是发行版信息, 右边是cpu等信息, 倒数第2行左边是窗口列表, 右边是登陆信息. 觉得它下边占了两行太浪费了, 我希望只占一行, 左边是窗口列表, 右边是 cpu等信息. 所以需要改它的profile 文件:

sudo vi ~/.byobu/profile

在这个文件最后找到 hardstatus 和 caption 开头的那两行, 注释掉, 然后加入两行:

hardstatus ignore
caption always ‘%12`%?%-Lw%50L>%?%{=r}%n*%f %t%?(%u)%?%{-}%12`%?%+Lw%?%11` %= %130`%135`%102`%101`%129`%131`%127`%114`%115`%108`%134`%128`%125`%126`%113`%119`%133`%117`%116`%106`%104`%103`%105`%107`%136`%123`%132`%120`%121`’

同目录下还有个 status 文件, 定义了哪些信息需要在右下角显示.
编辑完后按 F5 刷新配置文件, 显示如下图:

使用过程中还发现点问题. 你用 byobu -S yc 新建一个 session, 用完后按 F6 detach, 然后恢复的时候不能象 screen 那样用 -r 参数恢复. 查了下, 原来 byobu 使用了它自己默认的 -S byobu

所以需要对 byobu 脚本做点修改:
sudo vi `which byobu`

找到 NAME=”-S $PKG” 那行 (79行左右), 在下面加入一句:
[ “$#” = “2” ] && [ “$1” = “-r” ] && NAME=

意思是当指定了 -r 参数时不用 byobu 它自己的名字. 这样就可以用 -r 来恢复session 了

以上引自:

http://www.cnblogs.com/Dario67/archive/2011/12/11/2284294.html

继续安装系统

昨天花了挺长时间来捣鼓自己的笔记本,光盘始终不行,不能识别Windows的安装盘,我估摸着是因为把盘格式化时格式错误的原因,因为我使用一个redhat光盘安装的时候可以用。所以在尝试windows无果的时候,果断选择优盘安装Linux。

开始使用的是centos,结果当时有点犯二了,非得拿着一个bin的dvd去做优盘启动,那么大的文件,写入到优盘里,也把空间占的差不多了,后来发现硬盘里还有ubuntu系统,就拿来用了。

按照教程,用老毛桃制作了优盘启动。笔记本修改bios,把ust hdd+放到首选项,重启。好了,可以直接安装了,比硬盘要好弄一些,比光盘更好弄(可能是用光盘我有点不太习惯,也不熟悉),直接进入图形化安装界面。当以为万事大吉,直接各种点下一步就可以的时候,出现了不懂的地方。。。各种分区,跟Windows完全不一样啊,不过可以确定的是安装的系统肯定要在笔记本硬盘上,这个好辨认。当时能做到这个自己觉得还是可以的,虽然忘了一步挺重要的,就是启动引导所放的位置。现在当然能想到,因为碰到了安装系统后不插上优盘没法启动的问题。。。上网各种搜,总结下来发现是启动引导放的位置不对,我的应该是把引导安装在优盘里了。

必须得改啊,总不能总是一直插着优盘,虽然说启动后就可以拔下来了~~(忽然想到,是不是那种类似Ukey的东西,是不是就是使用这种类似的方式,让那些没有Ukey的人不能启动一些特殊的机器?好吧,其实只是猜想,自己并不清楚)

找了半天,没有找到适用的可以解决这个问题的方法,反正有时间,直接重做了一个优盘启动系统,这次做优盘启动系统的时候按照《http://www.linuxidc.com/Linux/2012-11/74695.htm》里的过程,修改了一下快捷启动方式,改成了syslinux,暂时还不知道这个起啥作用的,应该是在安装系统时候,把启动引导写入到系统所在盘吧。

在重新安装系统的过程中,这次到选择安装类型的时候,注意到了,需要选择安装系统到的盘,果断选择笔记本硬盘,然后选择继续的时候,会提示没有定义跟文件目录,百度之,根据《http://blog.sina.com.cn/s/blog_a66cf8120101awej.html》里的说明,给自己系统的sda1设置挂载点“/”,然后继续,果断可以。

现在正在安装中~~ 有点慢  不过有时间 慢慢等~

安装Linux系统

闲来无事,准备在笔记本上重新安装一下linux,并在平时学习中多多使用,因为以后的工作中也要较多的使用linux了。

废话不多说,下载了grub,拷贝一个centos版本,先用6.3吧。使用虚拟光驱打开,把isolinux文件夹下的文件拷贝到当前目录。因为之前就准备装Linux,所以分区已经分好了,把整个F盘都格式化成ntfs了,前期工作基本完成。

把下载的grub打开,根据教程,可以只把其中三个文件拷贝到系统盘根目录就可以了,但是因为懒,图个方便,直接把所有文件都解压到系统盘根目录了。修改boot.ini,添加grub centos的引导。OK,重启。

进入系统选择目录,选择自己新添加的centos,进入后选择 from menu.lst already installed,

输入三个命令:kerner (hd0,6)/isolinux/vmlinuz,initrd (hd0,6)/isolinux/initrd.img,boot回车

选择语言,地区,还有起始位置,我是硬盘安装,当然选择硬盘,找到自己安装系统的盘的位置,怪了。。。。  木有进入图形安装界面。。。重启后仍然不行,中间好像加载驱动的时候,有两个文件没有找到。。啥情况?

好了,我要把整个光盘解压出来到这个盘,然后试试。

这种方式进入了界面安装模式,但是在选择使用哪一种方式安装系统的时候,晕乎了,不知道应该选哪一种。选择了replace所有当前linux系统的方式,进入后提示空间不够,估摸着是去xp系统的启动盘里找空余空间去了,不对,就回来重新选。

接着选择了在当前选择的分区中安装系统,好了,可以进入剩下的选项了。然而悲催的是,这种安装方式似乎会重写整个引导盘。中间在格式化当前盘并安装的时候报错了,因为我把要安装的系统选择的是存放安装文件的分区。安装时会格式化,可以又会从这个盘里去读取文件,于是果断悲剧了~~

报错,然后自动重启,然后,就木有然后了。。。 因为现在进入系统是missing operating system.

 

已经被改变了。

挺长时间了,其实自己一直没有觉察,这种以前所没有的改变。

上次老师介绍了这个女孩,本着试试看的态度去沟通了一段时间。当然最终的结果还早,现在什么也没法说,不过能肯定的是,基本不可能成为两口子了,因为价值观什么的差距太大。

也许我对她有一些影响,不过我并不能发现,因为之前并不认识她,也不了解她。据她说是已经有了一些改变,因为她自己本身也正好准备着在做改变。然而,她对我的改变,却让我慢慢的体会到了一些,虽然这种变化其实并不是源自她主动。

以前的时候,我心里想起一个女孩,那种没有什么血缘关系的女孩,除非确实没有任何兴趣,总是有些乱七八糟的想法。这个样子并不好,我自己的心态调整的不好,导致自己在与其他异性交流的时候,会发生一些自己并不像要的事情。而那个时候的我,可以说,是滥情,滥用情。当然不是跟人随意发生关系,那样不是滥情,那是流氓啦,呵呵随着跟这个女孩的交流越来越多,我自己的想法不断的发生着变化,但那个时候并无所察觉。察觉到的时候是现在。那种乱七八糟的想法已经明显少了,甚至没有。我对女人,越来越挑剔,或者说,较少的被欲望驱使,而更多的被自己的心牵引。

当这个状态发生变化的时候,我越来越多将精力放在应该放的位置,而不是花在毫无意义的事情上。越来越清晰的认识清楚自己想要的是什么,虽然仍然没有一个清晰的想法,但是,我已经能将精力好好的放在眼前所发生的事情上,尽力去做好眼前的事情。

期间想起了一句话,我已经忘掉了过去,放弃了未来,我所能拥有和必须拥有的,只有现在。

也许不要想太多,认认真真把最眼前的事情做好,才是自己轻松自如走下去的更好的方法。

人家说,一个人,必须十分努力,才能看起来毫不费力。这点我十分赞同,因为是切身体验。

当你看到别人在某个平台上如鱼得水的时候,不能忘了他在展示之外的时间做了多少工作花了多少时间解决了多少难题,这,才是他如鱼得水的能力的来源。

赋闲随感

自离职以来已经让自己闲了将近一个月了,之前是完整的休息了差不多一个多周,然后开始找工作。工作的事情不是像自己想象的那么顺利,中间经历了一些曲折,然而终究有了个结果,得来并不容易。

最开始离职的时候心里抱有的那份梦幻般的自信也受到了不少打击,先是内推受阻,自己玩的时间也有点多,面试的相关内容却没有好好准备。自控能力明显下降,这是自己懒惰的最直接表现。内推的面试回来之后,才有着深深的懊悔,懊恼自己没有好好准备,以为自己脑袋里记住的那点东西足以应付各种面试,足以征服任何自己要去面试的职位。

眼高手低,自恋自大。最近相当一段时间以来自己似乎都是这个状态。直到开始找工作,让今年并不太好的就业形势一点一点打磨着自己,刺激着自己,惊醒着自己,好在终于醒了过来,为时未晚。

自工作以来,工作上的变动并不少,之前的一步一步的变动,现在看来由于自己不少的决定由于信息劣势的客观因素和躁动不安的内心的主观因素,导致自己的决策并不那么好,也许是当时比较好的选择,但同时也造就了今天的困境。

鉴于工作变动较多,自己缺乏稳定宽松的环境用来提高和学习,因此对这次的工作选择格外慎重。因为接下来的这个工作不只是想要换个环境,有个学习的机会,更重要的是自己一个选择行业的机会,而计划中接下来几年内会在同一个公司同一个行业内深入发展,使得这次的选择又格外的重要。

先写到这里,回头继续。