2014年1月30日星期四

Java多线程系列--“JUC集合”07之 ArrayBlockingQueue - 如果天空不死

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Java多线程系列--"JUC集合"07之 ArrayBlockingQueue - 如果天空不死  阅读原文»

概要

本章对Java.util.concurrent包中的ArrayBlockingQueue类进行详细的介绍。内容包括:
ArrayBlockingQueue介绍
ArrayBlockingQueue原理和数据结构
ArrayBlockingQueue函数列表
ArrayBlockingQueue源码分析(JDK1.7.0_40版本)
ArrayBlockingQueue示例

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3498652.html

ArrayBlockingQueue介绍

ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列。
线程安全是指,ArrayBlockingQueue内部通过“互斥锁”保护竞争资源,实现了多线程对竞争资源的互斥访问。而有界,则是指ArrayBlockingQueue对应的数组是有界限的。 阻塞队列,是指多线程访问竞争资源时,当竞争资源已被某线程获取时,其它要获取该资源的线程需要阻塞等待;而且,ArrayBlockingQueue是按 FIFO(先进先出)原则对元素进行排序,元素都是从尾部插入到队列,从头部开始返回。

注意:ArrayBlockingQueue不同于ConcurrentLinkedQueue,ArrayBlockingQueue是数组实现的,并且是有界限的;而ConcurrentLinkedQueue是链表实现的,是无界限的。

ArrayBlockingQueue原理和数据结构

ArrayBlockingQueue的数据结构,如下图所示:

说明
1. ArrayBlockingQueue继承于AbstractQueue,并且它实现了BlockingQueue接口。
2. ArrayBlockingQueue内部是通过Object[]数组保存数据的,也就是说ArrayBlockingQueue本质上是通过数组实现的。ArrayBlockingQueue的大小,即数组的容量是创建ArrayBlockingQueue时指定的。
3. ArrayBlockingQueue与ReentrantLock是组合关系,ArrayBlockingQueue中包含一个ReentrantLock对象(lock)。ReentrantLock是可重入的互斥锁,ArrayBlockingQueue就是根据该互斥锁实现“多线程对竞争资源的互斥访问”。而且,ReentrantLock分为公平锁和非公平锁,关于具体使用公平锁还是非公平锁,在创建ArrayBlockingQueue时可以指定;而且,ArrayBlockingQueue默认会使用非公平锁。
4. ArrayBlockingQueue与Condition是组合关系,ArrayBlockingQueue中包含两个Condition对象(notEmpty和notFull)。而且,Condition又依赖于ArrayBlockingQueue而存在,通过Condition可以实现对ArrayBlockingQueue的更精确的访问 -- (01)若某线程(线程A)要取数据时,数组正好为空,则该线程会执行notEmpty.await()进行等待;当其它某个线程(线程B)向数组中插入了数据之后,会调用notEmpty.signal()唤醒“notEmpty上的等待线程”。此时,线程A会被唤醒从而得以继续运行。(02)若某线程(线程H)要插入数据时,数组已满,则该线程会它执行notFull.await()进行等待;当其它某个线程(线程I)取出数据之后,会调用notFull.signal()唤醒“notFull上的等待线程”。此时,线程H就会被唤醒从而得以继续运行。
关于ReentrantLock,公平锁,非公平锁,以及Condition等更多的内容,可以参考:

(01) Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock
(02) Java多线程系列--“JUC锁”03之 公平锁(一)
(03) Java多线程系列--“JUC锁”04之 公平锁(二)
(04) Java多线程系列--“JUC锁”05之 非公平锁
(05) Java多线程系列--“JUC锁”06之 Condition条件

ArrayBlockingQueue函数列表

// 创建一个带有给定的(固定)容量和默认访问策略的 ArrayBlockingQueue。
ArrayBlockingQueue(int capacity)
// 创建一个具有给定的(固定)容量和指定访问策略的 ArrayBlockingQueue。
ArrayBlockingQueue(int capacity, boolean fair)
// 创建一个具有给定的(固定)容量和指定访问策略的 ArrayBlockingQueue,它最初包含给定 collection 的元素,并以 collection 迭代器的遍历顺序添加元素。
ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c)

// 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量),在成功时返回 true,如果此队列已满,则抛出 IllegalStateException。
boolean add(E e)
// 自动移除此队列中的所有元素。
void clear()
// 如果此队列包含指定的元素,则返回 true。
boolean contains(Object o)
// 移除此队列中所有可用的元素,并将它们添加到给定 collection 中。
int drainTo(Collection<? super E> c)
// 最多从此队列中移除给定数量的可用元素,并将这些元素添加到给定 collection 中。
int drainTo(Collection<? super E> c, int maxElements)
// 返回在此队列中的元素上按适当顺序进行迭代的迭代器。
Iterator<E> iterator()
// 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量),在成功时返回 true,如果此队列已满,则返回 false。
boolean offer(E e)
// 将指定的元素插入此队列的尾部,如果该队列已满,则在到达指定的等待时间之前等待可用的空间。
boolean offer(E e, long timeout, TimeUnit unit)
// 获取但不移除此队列的头;如果此队列为空,则返回 null。
E peek()
// 获取并移除此队列的头,如果此队列为空,则返回 null。
E poll()
// 获取并移除此队列的头部,在指定的等待时间前等待可用的元素(如果有必要)。
E poll(long timeout, TimeUnit unit)
// 将指定的元素插入此队列的尾部,如果该队列已满,则等待可用的空间。
void put(E e)
// 返回在无阻塞的理想情况下(不存在内存或资源约束)此队列能接受的其他元素数量。
int remainingCapacity()
// 从此队列中移除指定元素的单个实例(如果存在)。
boolean remove(Object
面试准备 - HashTable 的C#实现 开发地址法 - 听说读写  阅读原文»

Hashtable是很经常在面试中遇到的数据结构,因为他的O(1)操作时间和O(n)空间

之所以自己写一份是因为:

  • 加深对于hashtable的理解
  • 某些公司面试的时候需要coding.......

开发地址法 Xn=(Xn-1 +b ) % size

理论上b要和size是要精心选择的,不过我这边没有做特别的处理,101的默认size是从c#源代码中抄袭的。。。。

代码尽量简单一点是为了理解方便

hashtable快满的时候扩展一倍空间,数据和标志位还有key 这三个数组都要扩展

删除的时候不能直接删除元素,只能打一个标志(因为用了开放地方方法)

目前只支持string和int类型的key(按位131进制)


public class Hashtable<T>

{
public Hashtable()
{
this.dataArray = new T[this.m];
this.avaiableCapacity = this.m;
this.keyArray = new int[this.m];
for (int i = 0; i < this.keyArray.Length; i++)
{
this.keyArray = -1;
}
this.flagArray = new bool[this.m];
}

private int m = 101;

private int l = 1;

private int avaiableCapacity;

private double factor = 0.35;

private T[] dataArray;

private int[] keyArray;

private bool[] flagArray;

public void Add(string s, T item)
{
if (string.IsNullOrEmpty(s))
{
throw new ArgumentNullException("s");
}

if ((double)this.avaiableCapacity / this.m < this.factor)
{
this.ExtendCapacity();
}

var code = HashtableHelper.GetStringHash(s);
this.AddItem(code, item, this.dataArray, code, this.keyArray, this.flagArray);
}

public T Get(string s)
{
if (string.IsNullOrEmpty(s))
{
throw new ArgumentNullException("s");
}

var code = HashtableHelper.GetStringHash(s);
return this.GetItem(code, this.dataArray, code, this.keyArray, this.flagArray);
}

private void ExtendCapacity()
{
this.m *= 2;
this.avaiableCapacity += this.m;
T[] newItems
= new T[this.m];
int[] newKeys = new int[this.m];
bool[] newFlags = new bool[this.m];

for (int i = 0; i < newKeys.Length; i++)
{
newKeys
= -1;
}

for (int i = 0; i < this.dataArray.Length; i++)
{
if (this.keyArray >= 0 && !this.flagArray)
{
//var code = HashtableHelper.GetStringHash(s);
this.AddItem(
this.keyArray,
this.dataArray,
newItems,
this.keyArray,
newKeys,
this.flagArray);
}
}
this.dataArray = newItems;
this.keyArray = newKeys;
this.flagArray = newFlags;
// throw new NotImplementedException();
}

private int AddItem(int code, T item, T[] data, int hashCode, int[] keys, bool[] flags)
{
int address =

阅读更多内容

2014年1月28日星期二

PHP成长记(三) —— SSO单点登录/登出

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
PHP成长记(三) ―― SSO单点登录/登出  阅读原文»

用户名:村长爱技术
文章数:24
评论数:19
访问量:6533无忧币:430博客积分:434:3 注册日期:2013-12-18

  • 三日内更新
PHP成长记(三) ―― SSO单点登录/登出

你有没有遇到过公司每一个产品,都要开发一个用户系统,浪费开发成本不说,用户体验还不好,用户要记住每一个产品的用户密码,每个产品都要重复登录,问题重重,要是能登录一次别的一些列产品就都登录了那该多好,SSO(Single Sign On)单点登录,能帮你解决这些问题。

我在这里来说一下单点登录实现原理,希望能让大家对单点登录更了解,并应用之。我这里以phpCAS的例子来说讲解。

首先我们想到单点登录可能是通过在根域下设置一个cookie,然后只要在这个域下的都可以共享cookie,这种方式最大的问题就是不能实现跨域(虽然网上有很多跨域的解决方案,比如header方式,但是各个浏览器支持的都不是很好),并且很不安全。所以CAS实现了另一种方式――cas server和cas client分离,也就是说单点登录服务器单独部署,其他client调用它,从而实现单点登录。具体流程如下图

wKioL1LmEoXAB32OAAKlQIXqKhA161.jpg

1、浏览器访问单点登录的网站,如果session存在就返回数据,如果不存在就跳转到cas server(一个单独域名的服务)

2、如果有已经登录过,通过检测cookie,cas server就会302跳转通过url返回Ticket(Ticket是随机且唯一)到网站,如果没有登录过,就跳转到cas server登录页面进行登录,登录成功设置cookie,然后302跳转返回Ticket到网站,同时cas server会存储改Ticket、cookie和网站host的对应关系

3、 网站接收到Ticket后通过cas server提供的校验url去校验Ticket,cas server确认后返回成功,网站把当前的sessionid换成Ticket(session_id(Ticket)),然后返回浏览器请求数据

4、当用户再访问网站的时候,就会判断当前session是否登录

单点登录就说完了,其实没有太复杂的技术,主要是实现的思想,说完单点登录大家一定想知道的是如何单点登出呢?接下来我再分析一下单点登出的原理:

wKiom1LmGDLTq923AAG-XpjR3Fo623.jpg

1、用户点击登出,网站先清除当前网站的session信息,然后跳转到cas server退出URL

2、cas server接收到登出请求后删除cookie或session信息,并且通过单点登录时候记录的cookie和host、Ticket对应关系,遍历host给网站发送post登出请求

3、网站接收到登出请求后,获取Ticket,并且把Ticket换成当前的sessionid,模拟用户登录,然后销毁session完成登出

以上是本人通过研究phpCAS获得的结论,这个只是最基本的模式,还有很多复杂模式,比如代理模式等等,有经验的朋友欢迎交流!

谢谢!

本文出自 "村长爱技术" 博客,请务必保留此出处http://weijingwu.blog.51cto.com/8376555/1355109

foreach循环对异步委托的影响  阅读原文»

foreach循环对异步委托的影响

在使用foreach对异步委托赋值的时候,发现一个问题。代码如下:

static void Main(string[] args)
List<Task> lst_tsk = new List<Task>();
List<int> lst_item = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (var item in lst_item)
Task tsk = new Task(() =>
Console.WriteLine(item);
Console.ReadLine();

往Task中,赋值一个拉姆达表达式,期待运行的结果应该是1,2,3,4,5,6,7,8,9,10乱序输出。但是实际上的结果是10,10,10,10,10,10,10,10,10,10。很多人都认为这是c#编译器的一个bug。Eric做出了解释,根据Eric的文章,在foreach循环语句中的变量只有一个item,该变量在循环过后,被赋值为10了。当异步线程启动的时候,取到的item早就变成10了,因此就得出上面的结果。

根据Eric的文章,foreach只是一个语法糖,它对应的代码如下

IEnumerator<int> e = ((IEnumerable<int>)values).GetEnumerator();
int m; // OUTSIDE THE ACTUAL LOOP
while(e.MoveNext())
m = (int)(int)e.Current;
funcs.Add(()=>m);
if (e != null) ((IDisposable)e).Dispose();

可以看到m并不包括在while语句中,而且()=>m的意思是返回当前m变量的值,而不是返回委托创建时m变量的值。因此当这个委托真正运行的时候,找到的m可能已经是其它值了。

如果把语法糖改成如下的方式:

while(e.MoveNext())
m = (int)(int)e.Current;

那么m在while内部,每一个m都是单独的。根据Eric,不这样改的一个原因就是,它可能会增加了在循环中使用闭包的次数,(因为异步线程在启动时,都会用到循环中的m,这个m的生命周期在while循环中,只能通过闭包机制,使得其值能够继续保留在内存中,能够让异步委托在调用的时候继续访问到该值)。而且,如果这样修改了,用户会觉得foreach每一个循环都使用了一个新的变量,而不是一个存储了新值的旧变量。

因此,一开始的演示代码,只需要如下修改既可以了:

static void Main(string[] args)
List<Task> lst_tsk = new List<Task>();
List<int> lst_item = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (var item in lst_item)
var copy= item;//增加一个临时的拷贝变量
Task tsk = new Task(() =>
Console.WriteLine(copy );
Console.ReadLine();

这样的话,每次委托运行的时候,都会去找copy 变量了。

可能是很多人的意见影响了C#编译器团队,在C#5.0中,他们决定修改这个问题,foreach循环中的变量存在于循环中,因此每次循环都使用的是一个新的变量。for循环暂时不做修正。因此,演示代码在VS2012下,使用C#5.0的编译器编译,得到的结果是如预期那样的乱序输出。

本文出自 "一只博客" 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1355032

分享至 一键收藏,随时查看,分享好友!

阅读更多内容

回家前的挣扎——SQLite增删改查 - wolfy

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
回家前的挣扎――SQLite增删改查 - wolfy  阅读原文»

引言

最后一天,公司就两个人,也不知道弄点什么,就在网上找了Sqlite的文档,看了看,这里也是现学现卖,给自己找点事做,感觉时间过得还是比较快的,不然焦急等待,滋味不好受啊。

SQLite简介

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至今已经有13个年头,SQLite也迎来了一个版本 SQLite 3已经发布。(百度百科)

SQLite使用

跟使用sqlhelper一样封装sqlitehelper,通过下面的代码你会发现他们是非常的相似的。

1 public class SQLiteHelper
2 {
3 private static readonly string databaseName = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["databaseName"];
4 /// <summary>
5 /// 创建数据库
6 /// </summary>
7 /// <param name="databaseName">数据库文件路径</param>
8 public static void CreateDataBase()
9 {
10 if (!File.Exists(databaseName))
11 {
12 SQLiteConnection.CreateFile(databaseName);
13 }
14 }
15 /// <summary>
16 /// 获得连接对象
17 /// </summary>
18 /// <returns></returns>
19 public static SQLiteConnection GetSQLiteConnection()
20 {
21 #region 方法一
22 SQLiteConnectionStringBuilder connStr = new SQLiteConnectionStringBuilder();
23 connStr.DataSource = databaseName;
24 connStr.Password = "123456";
25 connStr.Pooling = true;
26 return new SQLiteConnection(connStr.ToString());
27

2014年1月27日星期一

贰零壹叁 - 那一缕阳光

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
贰零壹叁 - 那一缕阳光  阅读原文»

转眼间,2013年已渐渐逝去,回首2013,是我的一个转折点。 2013年,是我走出校园,走进社会,踏上工作岗位的第一年。这一年,使我对人生、对社会的看法产生了极大的变化。以往,我以为人生是美丽而丰富多彩的,社会上的每个人都是是和谐、天天向上的,然而,当我涉足社会的第一年,让我感到,社会并不像自己想...

json解析之jackson ObjectMapper - treerain  阅读原文»

Json解析常用的有fastjson和jackson,性能上网上有不少的对比,说是fastjson比较好,今天先整理一下jackson的东西,后面再发一个fastjson的。

jackson是spring mvc内置的json转换工具,fastjson则是阿里做的开源工具包。

jackson序列化如下:

1 /**
2 * json serialize
3 * @param obj
4 * @return
5 */
6 public static String jsonSerialize(final Object obj) {
7 ObjectMapper om = new ObjectMapper();
8 try {
9 return om.writeValueAsString(obj);
10 } catch (Exception ex) {
11 return null;
12 }
13 }

jackson反序列化如下:

1 /**
2 * json deserialize
3 * @param json
4 * @param mapClazz
5 * @return
6 */
7 public static Object jsonDeserialize(final String json, final Class<?> mapClazz) {
8 ObjectMapper om = new ObjectMapper();
9 try {
10 return om.readValue(json, mapClazz);
11 } catch (Exception ex) {
12 return null;
13 }
14 }

在使用的过程中,很有可能会遇到json反序列化的问题。当你对象中有get***()的地方,它就当做它是一个属性,所以当你序列化json之后,在反序列化的时候,很有可能会出现异常的情况,因为在你的model中没有这个***的定义。

那该如何处理和解决呢?

jackson给出了它自己的解决方案(JacksonHowToIgnoreUnknow):

1. 在class上添加忽略未知属性的声明:@JsonIgnoreProperties(ignoreUnknown=true)

2. 在反序列化中添加忽略未知属性解析,如下:

1 /**
2 * json deserialize
3 * @param json
4 * @param mapClazz
5 * @return
6 */
7 public static Object jsonDeserialize(final String json, final Class<?> mapClazz) {
8 ObjectMapper om = new ObjectMapper();
9 try {
10 // 忽略未知属性
11 om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
12 return om.readValue(json, mapClazz);
13 } catch (Exception ex) {
14 return null;
15 }
16 }

3. 添加"Any setter"来处理未知属性

1 // note: name does not matter; never auto-detected, need to annotate
2 // (also note that formal argument type #1 must be "String"; second one is usually
3 // "Object", but can be something else -- as long as JSON can be bound to that type)
4 @JsonAnySetter
5 public void handleUnknown(String key, Object value) {
6 // do something: put to a Map; log a warning, whatever
7 }

4. 注册问题处理句柄

注册一个DeserializationProblemHandler句柄,来调用ObjectMapper.addHandler()。当添加的时候,句柄的handleUnknownProperty方法可以在每一个未知属性上调用一次。

这个方法在你想要添加一个未知属性处理日志的时候非常有用:当属性不确定的时候,不会引起一个绑定属性的错误。


本文链接:http://www.cnblogs.com/treerain/p/JacksonHowToIgnoreUnknow.html,转载请注明。

阅读更多内容

2014年1月26日星期日

【cocos2d-x从c++到js】12:回调函数1——按键回调

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
【cocos2d-x从c++到js】12:回调函数1――按键回调  阅读原文»

每日博报 精彩不止一点关闭
【cocos2d-x从c++到js】12:回调函数1――按键回调

回调函数是界面交互和接入各种第三方SDK的关键所在,因为回调函数的C++代码是不能自动生成的,一切的一切,都需要手写完成。

比较不错的是,Cocos2d-x引擎对于回调函数提供了完整的包装机制。我们所需要做的就是了解这个机制,并使用他。学习引擎自己的代码例子,可以比较快速准确的上手这一机制。

首先,我们在Cocos2d-x 3.0 beta版中,使用他自带的工程创建工具,新建一个跨平台的JS项目。按照惯例,这是一个helloworld项目。在XCode运行时,我们可以看到:

可以看到右下角的回调按钮。我们来看看他是怎么实现的。分成两个过程来做:

一、绑定回调函数过程

首先,我们要去找回调函数JS的绑定代码,在myApp.js中,init函数里面,可以看到如下代码:

3
4
5
6
7
8
9
10
11
12
// add a "close" icon to exit the progress. it's an autorelease object
var closeItem = cc.MenuItemImage.create(
"res/CloseNormal.png",
"res/CloseSelected.png",
function () {
cc.log("close button was clicked.");
},this);
closeItem.setAnchorPoint(cc.p(0.5, 0.5));
var menu = cc.Menu.create(closeItem);
menu.setPosition(cc.p(0, 0));
this.addChild(menu, 1);
closeItem.setPosition(cc.p(size.width - 20, 20));

cc.MenuItemImage.create函数的第三个参数,绑定了匿名回调函数。第四个参数,传入的是回调函数调用时的this(如果不理解JS的this机制,请先阅读一些JS的资料)。这些都是意图和作用很明显的JS代码,不用细说。

然后,我们去看底层对应执行的C++代码。在cocos2d_specifics.cpp文件中,找到js_cocos2dx_CCMenuItemImage_create函数。

37
38
39
40
41
42
43
44
45
46
// "create" in JS
JSBool js_cocos2dx_CCMenuItemImage_create(JSContext *cx, uint32_t argc, jsval *vp)
{
if (argc >= 2 && argc <= 5) {
jsval *argv = JS_ARGV(cx, vp);
JSStringWrapper arg0(argv[0]);
JSStringWrapper arg1(argv[1]);
JSStringWrapper arg2;
bool thirdArgIsString = true;
if (argc >= 3) {
thirdArgIsString = argv[2].isString();
arg2.set(argv[2], cx);
last = 3;
}
}
jsThis = argv[last];
}
}
else {
linux系统使用yum仓库出现的错误总结  阅读原文»

linux系统使用yum仓库出现的错误总结

1.用yum安装软件出现磁盘空间满

  [root@node1 ~]# yum install ftp     --安装软件出现错误  ...................................  Error Downloading Packages:  ftp-0.17-53.el6.i686: Insufficient space in download directory /var/cache/yum/i386/6/c6-tong/packages  * free   0  * needed 56 k  [root@node1 ~]#  

图:

wKiom1LjXnnjIy0qAAIOzJxrKa0616.jpg

解决方法:

  [root@node1 ~]# df -h      --查看磁盘空间,空间已满  文件系统          容量  已用  可用 已用%% 挂载点  /dev/mapper/VolGroup-lv_root  6.5G  6.1G     0 100% /      --根分区空间已满,清除文件  tmpfs                 504M     0  504M   0% /dev/shm  /dev/sda1             485M   46M  414M  10% /boot  /dev/sr0              3.6G  3.6G     0 100% /mnt  [root@node1 home]# df -h       --清除后的结果  文件系统          容量  已用  可用 已用%% 挂载点  /dev/mapper/VolGroup-lv_root  6.5G  1.9G  4.2G  31% /  tmpfs                 504M     0  504M   0% /dev/shm  /dev/sda1             485M   46M  414M  10% /boot  /dev/sr0              3.6G  3.6G     0 100% /mnt  [root@node1 home]#  

测试结果:

  [root@node1 home]# yum install ftp     --安装成功  Loaded plugins: fastestmirror  Determining fastest mirrors  c6-tong  ........................................  Running Transaction  Installing : ftp-0.17-53.el6.i686                                                                                                                   1/1  Verifying  : ftp-0.17-53.el6.i686                                                                                                                   1/1  Installed:  ftp.i686 0:0.17-53.el6  Complete!  [root@node1 home]#  

2.用yum使用网络源,出现网络不通

  [root@node1 yum.repos.d]# yum install squid  Loaded plugins: fastestmirror  Loading mirror speeds from cached hostfile  Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=i386&repo=os error was  14: PYCURL ERROR 6 - "Couldn't resolve host 'mirrorlist.centos.org'"  Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch=i386&repo=centosplus error was  14: PYCURL ERROR 6 - "Couldn't resolve host 'mirrorlist.centos.org'"  ^C^C^C^Z  [1]+  Stopped                 yum install squid  [root@node1 yum.repos.d]# ping www.baidu.com  ^C  

解决方法:(检查网络)

wKiom1LjZK_QIjqUAAIYF6-U5j4224.jpg

测试结果:

wKiom1LjZhDh-nn5AADUmIIL1ik482.jpg

3.使用yum安装软件包出现进程占用

wKiom1LjZT3jdvgRAAHpqT_hsVg183.jpg

解决方法:

wKioL1LjZVeDvnuHAABLcTcxfpk509.jpg

测试结果:

wKioL1LjZbLBoxqVAADUmIIL1ik182.jpg

Linux搭建网络源:http://tongcheng.blog.51cto.com/6214144/1338949

Linux搭建本地源:http://tongcheng.blog.51cto.com/6214144/1338876

本文出自 "一起走过的日子" 博客,谢绝转载!

阅读更多内容

2014年1月25日星期六

今天你跳槽了吗? - 我和小菜

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
今天你跳槽了吗? - 我和小菜  阅读原文»

时间过的好快,一眨眼今天都1月26了(农历腊月26),祝福自己生日快乐,离开学校已经快五年的时间了,而自己踏上IT工作才一年多一点的时间,前天刚刚公司开完年会后,鸡冻人心的抽奖居然没有我,OH MY GOD! 不过彩票中了十块钱算是对自己的安慰奖了,哈哈!

年底产生了跳槽的想法,具体原因我就不说什么了,只是用这篇文章来写写关于跳槽的一些想法。

昨天和一位同行聊了两句"不加工资的挽留就是耍流氓",说的也算对,人都是生活在现实当中的,现在的物质奖励是最靠谱的,其他都是空话。老板每个月都延迟发工资,无偿加班,你会继续愿意无私奉献的效劳公司吗?你和公司存在的关系我想最直接的就是利益关系了,当两者的利益发生了扭曲变形,你是不是要考虑一下换一个地方了?这个可以理解为―"跳槽"!

每一次的跳槽都是很蛋疼的一件事

也是一件很苦恼的事

对于离职的个人观点

  1. 有下一家在跳。这样的好处是万一跳槽失败,还能有个糊口的工作。不会两面工作都没捞着,成为无业游民。
  2. 不要指望一下子能够跳到多么好的公司。绝大多数公司都是一个样子,只是企业理念和薪资制度可能会有细小的差异。
  3. 不要一味地指望进大公司。大公司已经基本都形成了自己的规模和体制,虽然进入待遇和福利也许不错,但是不要指望很快能够发展和升职。一旦进入了大公司,你会发现像我们这个年龄段的,大多都是在做一些基层的工作,即使有些人根本没有多少能力,但是很不幸,他们是老员工,有资历。
  4. 不要一味地指望跳槽就能够从一个开发者一下升迁为经理。即使有这个机会,也要衡量衡量,这个公司真的值得信任吗?绝大多数公司的中层都是从公司内部诞生出来的。正规而又有发展趋势的公司一般不会从外面招聘比较重要的职务,比如项目经理,项目架构师等。
  5. 不要一味地用薪水和奖金来衡量跳槽的好坏。真的衡量的标准只有三个:第一是这个公司是不是正处于发展时期,而且有很大的发展空间;第二是这份工作是不是一个挑战,一个新的尝试,是不是自己所希望的工作;第三,在接受这份工作的时候,会不会对你未来5年的发展产生一定的影响。
  6. 不要一味地指望外企。不可否认外企的待遇很好,举例:北京很少有外企从事产品研发工作,即使是像IBM这样的公司,你会发现一旦你进入之后,你不熬个四五年很难升一级;而且你还会发现,你做的只是测试和无聊的coding。
  7. 一定要注意你的交流圈子。如果到目前为止,你还没有一个属于你的而且比较不错的交流圈子,那么一定要注意了。跳槽的时候有朋友帮忙,会省去很多麻烦,也会获取一些更加容易的机会。
  8. 最后一条也是最重要的一条,你具备享受更好待遇的实力吗?人往高处走是不假,但是追求高待遇的你,是否也具备高待遇所对应的高实力呢?只要有好的技术能力和业务能力,不愁找不到更好的下家。相反,水平一般却想获取高回报的想法则不太现实。

说了这几点,希望大家可以对我的观点进行讨论,如果觉得文章在这个即将到来的跳槽大战可以帮助到你,可以推荐一下哦!

将来的你一定会感激现在拼命的自己


本文链接:http://www.cnblogs.com/wohexiaocai/p/3533821.html,转载请注明。

工作流activiti-02事物控制、流程引擎创建 - L凯林  阅读原文»

使用activiti中有个很重要的问题就是需要保证事物的控制

activiti使用的是mybatis作为orm技术 封装了一系列的操作数据库操作 这也就是大家调用的api 操作的数据库表都是activit自带的数据表 一般情况下使用spring整合

activiti的事物是很强大的 但是往往就不能如愿 因为公司使用的都是自己的框架不能利用spring来整合事物。

通过java程序来控制activiti的事物

activiti的事物依赖于TransactionFactory 在创建流程引擎ProcessEngine来指定事物工厂,其原因分析如下:

创建流程引擎: ProcessEngine processEngine = conf.buildProcessEngine() ;

conf为StandaloneProcessEngineConfiguration的对象其buildProcessEngine方法如下:

public ProcessEngine buildProcessEngine() {
init();
return new ProcessEngineImpl(this);
}

//调用init方法

protected void init() {
initHistoryLevel();
initExpressionManager();
initVariableTypes();
initBeans();
initFormEngines();
initFormTypes();
initScriptingEngines();
initBusinessCalendarManager();
initCommandContextFactory();
initTransactionContextFactory();
initCommandExecutors();
initServices();
initIdGenerator();
initDeployers();
initJobExecutor();
initMailScanner();
initDataSource();
initTransactionFactory();
initSqlSessionFactory();
initSessionFactories();
initJpa();
initDelegateInterceptor();
initEventHandlers();
}
其中初始化了很多信息,可以依次看看源码 其中initTransactionFactory()方法代码如下:

// myBatis SqlSessionFactory ////////////////////////////////////////////////

protected void initTransactionFactory() {
if (transactionFactory==null) {
if (transactionsExternallyManaged) {
transactionFactory = new ManagedTransactionFactory();
} else {
transactionFactory = new JdbcTransactionFactory();
}
}
}

其中transactionFactory为 protected TransactionFactory transactionFactory; 类中的属性
由代码可知 如果transactionFactory不为空则事物工厂为JdbcTransactionFactory的实例化对象
那么设置StandaloneProcessEngineConfiguration的transactionFactory的值为一JdbcTransactionFactory对象即可

代码如下:创建一个servlet监听器 在容器启动的时候创建一个流程引擎 (需要配置web.xml文件)

/**********************************************************************
* <pre>
* FILE : MyServletListener.java
* CLASS : MyServletListener
*
* AUTHOR : Liaokailin
*
* FUNCTION :
*
*
* Contact: Sina L凯林
*
*======================================================================
* CHANGE HISTORY LOG
*----------------------------------------------------------------------
* MOD. NO.| DATE | NAME | REASON | CHANGE REQ.
*----------------------------------------------------------------------
* |2014年1月17日|Liaokailin| Created |
* DESCRIPTION:
* </pre>
***********************************************************************/
package com.infodms.dms.actions;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

import com.infodms.dms.db.DBManager;
import com.infodms.dms.utils.DmsActivitiTransactionFactory;

public class MyServletListener implements ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent arg0) {
ProcessEngines.destroy();
}

@Override
public void contextInitialized(ServletContextEvent arg0) {
StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
conf.setDataSource(DBManager.getDataSource()).setDatabaseSchemaUpdate("true").setDbHistoryUsed(true) ;
conf.setTransactionFactory(new DmsActivitiTransactionFactory()) ;
ProcessEngine processEngine = conf.buildProcessEngine() ;

}
}

conf.setTransactionFactory(new DmsActivitiTransactionFactory()) ;设置事物

DmsActivitiTransactionFactory代码如下:

/**********************************************************************
* <pre>
* FILE : DmsActivitiTransactionFactory.java
* CLASS : DmsActivitiTransactionFactory
*
* AUTHOR : Liaokailin
*
* FUNCTION :
*
*
* Contact: Sina L凯林
*
*======================================================================
* CHANGE HISTORY LOG
*----------------------------------------------------------------------
* MOD. NO.| DATE | NAME | REASON | CHANGE REQ.
*----------------------------------------------------------------------
* |2014年1月21日|Liaokailin| Created |
* DESCRIPTION:
* </pre>
***********************************************************************/
package com.infodms.dms.utils;

import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import com.infoservice.po3.core.context.DBService;


public class DmsActivitiTransactionFactory extends JdbcTransactionFactory {

@Override
public Transaction newTransaction(Connection conn, boolean autoCommit) {
System.out.println("开启新的事物");
return new DmsActitiviTransaction(conn,autoCommit) ;
//return (Transaction) DBService.getInstance().getTransaction() ;
}

@Override
public void setProperties(Properties props) {
super.setProperties(props);
}

}

DmsActitiviTransaction 代码如下:

/**********************************************************************
* <pre>
* FILE : DmsActitiviTransaction.java
* CLASS : DmsActitiviTransaction
*
* AUTHOR : Liaokailin
*
* FUNCTION :
*
*
* Contact: Sina L凯林
*
*======================================================================
* CHANGE HISTORY LOG
*----------------------------------------------------------------------
* MOD. NO.| DATE | NAME | REASON | CHANGE REQ.
*----------------------------------------------------------------------
* |2014年1月21日|Liaokailin| Created |
* DESCRIPTION:
* </pre>
***********************************************************************/
package com.infodms.dms.utils;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.ibatis.transaction.jdbc.JdbcTransaction;

import com.infodms.dms.db.DBManager;
import com.infoservice.po3.core.context.DBService;

public class DmsActitiviTransaction extends JdbcTransaction {
private static Connection conn = null ;
public DmsActitiviTransaction(Connection connection,
boolean desiredAutoCommit) {
//connection.setAutoCommit(desiredAutoCommit);
super(connection, desiredAutoCommit);
try {
connection.setAutoCommit(desiredAutoCommit);
} catch (SQLException e) {
e.printStackTrace();
}

}

@Override
public Connection getConnection() {
/*DBService d = DBService.getInstance() ;
d.loadConf("/DataAccessContext.xml");
return d.getConnection() ;*/
// return DBService.getInstance().getConnection() ;
try {
if(conn==null){
synchronized (DmsActitiviTransaction.class) {
conn = DBManager.getConnection() ;
}
}
return conn ;
} catch (Exception e) {
System.out.println("获取链接失败:"+e);
return null ;
}
}

@Override
public void close() throws SQLException {
/*if(conn!=null&&!conn.isClosed()){
conn.close();
}*/
System.out.println("activit:close()");
}

@Override
public void commit() throws SQLException {
/*if(conn!=null&&!conn.isClosed()){
conn.commit();
}*/
System.out.println("activit:commit()");
}

@Override
protected void resetAutoCommit() {
System.out.println("resetAutoCommit()");
/*try {
if (conn != null && !conn.isClosed()) {
conn.setAutoCommit(false);
}
} catch (SQLException e) {
e.printStackTrace();

}*/
}

@Override
public void rollback() throws SQLException {
/*if(conn!=null&&!conn.isClosed()){
conn.rollback();
}*/
System.out.println("activit:rollback()");
}

@Override
protected void setDesiredAutoCommit(boolean arg0) {
System.out.println("setDesiredAutoCommit:"+arg0);
}


}

其中DBManager

/**********************************************************************
* <pre>
* FILE : DBManager.java
* CLASS : DBManager
阅读更多内容

2014年1月24日星期五

我想当架构师 - 菜鸟范

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
我想当架构师 - 菜鸟范  阅读原文»

在未来,我希望能成为一个架构师。
想要成为架构师,因为这个特殊的职位是团队的技术灵魂,是个领导众人合力的重要角色。成为一名架构师,才能在产品的开发者名单中位列前茅;才能洞悉各类高新技术,客观评判各种框架;才能养活自己、家人,买房买车,然后经常去旅个游什么的。其实我的性格可能很适合做架构师:
  1. 危机意识强,在危机面前能迅速找到解决方案;
  2. 习惯用模型化的观点看待世界,习惯用哲学视角学习技术;
  3. 能够站在一个比较高的层次去看待自己的项目、进度、人员素质之类的,并适时修整工作任务;
  4. 社交能力综合来说都不错,可以很快融入一个新的社交圈
  5. 对待压力的态度挺好的,不会懈怠、自卑什么的
  6. 对待工作的态度也挺好的,该我做好我会做好,不需要做好也会尽力去做(不该我做的我基本不会去碰的)
  7. 学习能力极强极强滴,这个方面灰常自信滴哟,学习新技术周期挺短的,但能迅速应用于项目;
不过也有很多有问题的地方:
  1. 做事不够坚持,哪怕这事是自己提出的;
  2. 学习的东西不够多,也不够系统,很多工作其实是用原始本能而不是科学方法去做的;
  3. 对新技术不太感冒,只关心工作需要用到的技术
  4. 在生活里面有拖延症,总是协调不好(这个,希望看完《自控力》能有所改善哟)
2014需要克服这些不好的习惯了,为了尽早成为一名合格的架构师,为了尽早达到自己希望的生活状态,需要好好学习,好好工作,好好努力才行。世界上有很多优秀的人,他们比我有能力太多了,比我又天分太多了,还比我努力很多,我必须比他们还努力才行,我必须克服性格上的很多缺点,为我的人生着想,为我以后的妻儿着想啊。明年有这样一些目标:
  1. 找一份比较有前景的工作,再苦再累,哪怕薪酬很低都不怕,只要能让我跳出现在的技术困局,学习LAMP、面向过程、面向服务之类的就行了(这可得保密哟)!
  2. 好好学习,技术、管理、为人、口才、外语都需要努力,Web、C++、C、Ruby、Java、Lisp都是极好极好的;
  3. 多看些书,多买些书,尽快整一个读书清单,然后耐下性子去看吧
  4. 克服性格上很多缺陷,做到:言出必行、准时、事前多思考,多考虑
  5. 多关注技术,每一样新技术、新玩意都有许多创业契机,多想、多看、多学习
  6. 至少每个月写一篇博客,预期需要完成:Log4Net源码剖析、LAMP环境搭建、C++入门之类、面向对象的思维逻辑之类的,多关注网络编程、性能优化,深入到技术细节中去
  7. 在家人朋友那多花点时间、多花点心思,有事没事带几个侄子侄女去玩,给小外甥买点衣服、玩具、书什么的,给父母多点生活费,多回家。。。最最重要是多陪陪女朋友,陪她去逛街旅游,白日做梦,给她多一些浪漫,少一些忧愁
  8. 出去旅游,可以去:汕头、杭州、上海、海南之类的
2014年是一个契机,人生的方向、生活的方向、学习的方向可能都会在这一年定下来了,Good good study, Day day up。

本文链接:http://www.cnblogs.com/LuoFan/p/3533186.html,转载请注明。

一个前端与后端分离的架构实例 - 麦舒  阅读原文»

看了《系统架构:Web应用架构的新趋势---前端和后端分离的一点想法》 这篇文章,对前端与后端的分离非常认同,这样做对于系统的维护是有相当大的好处的。正好自己也设计了一个这样的系统,于是把它拿出来,和大家讨论一下。这个架构,与其说是想出来,还不如说是我做系统总结出来的最佳实践。

我们做的系统,前端的页面基本都是使用 JavaScript 的富户端页面,主要应用的框架用,jquery、jquery ui、knockout js、Durandal、另外,还有自己封装的一些 UI 组件,后端的主要采用到的技术有 OData、MVC、Linq to SQL 以及自己写的一个权限管理组件,数据库采用的是 SQL Server 2005。

下面向大家介绍一下各模块的功能以及其划分的目的,我们先从用户界面看起吧

一、关于前端的 dataProvider

简单点说,就是一个给界面调用的数据访问层,很多人都人这样的疑问,在这里加一个数据访问层,是不是多余?只要你做的前端,你都会碰到下面这些问题:

1、一个产品或者项目,前端与后端是同时进行了,这时候,根本没有后端的接口,甚至可以说,连个接口的定义都没有。作为前端开发人员,你如何去开展自己的工作?

2、作为前端开发人员,你有没有碰到,因为后端的接口挂掉,导致你的工作没法继续做下去的情形?

3、作为前端开发人员,往往免不了要和第三方的接口进行对接,你有没有碰到过,和你做对接的人员,突然因为项目紧,被抽走了,留给你的只有一堆需要传N个参数,传了后接着出“对象为空”的异常呢?你根本不知道哪里参数传错了。面对这些接口,你除了破口大骂,得不到任何帮助。

4、作为前端开发人员,你有没有试过,你向后端的开发组,要一个接口,他们需要讨论个几天,然后再花几天才能给你,给你之后,还不能用,又得再花几天时间调试呢?

如果你向我一样,都曾经都碰过这些问题,你就不会怀疑这个 dataProvider 存在的必要了,有了这个 dataProvider,可以最大减少后端接口对前端开发的影响。下面是一个 dataProvider 的实例:

var dataProvider = (function () {

var fakeProvider = {
countries:
new Countries()
};

var realProvider = {
countries:
new JData.WebDataSource()
};

//下面的接口,根据情况二选一
return fakeProvider; //这个是假的 dataProvider,从本地读
return realProvider; //这个是真正 dataProvider,从接口读
})();

从上面可以看出来,这个 dataProvider 使用了工厂模式来创建,它有两个实例,fakeProvider和realProvider,fakeProvider是用来提供一些模拟数据,而realProvider提供从接口读取出来的数据。当没有接口,或者接口挂掉,我们可以先从 fakeProvider 来读取数据。等接口好了,切换到 realProvider 。

二、关于用户界面输入的验证

1、数据的验证。用户在界面输入数据后,接着调用 dataProvider 里的接口对数据进行处理,但是在向服务端提交之前,得先对数据进行验证。那个这个验证如何进行呢?dataProvider先从服务端获实体的描述信息,这些描述包括但不限于:主外键、属性的验证信息(比如是否可空),当然,这个实体信息是可以缓存起来,以便重用的。然后 dataProvider 再根据这个描述信息来对数据进行验证。

2、错误信息的显示

当验证到某一个属性不合法,验证信息的模块就在页面查找出对应输入控件,它是怎么查找的呢?比如说,Contry 的 Name 输入为空是不可以的。那它就先查找 id 为Coutry的元素,然后再Coutry元素下面再找id 或者 name 为 Name 的控件,如果找不到则直接弹窗显示错误信息。例如:

<form id="Country">
<input name="Name"/>
</form>

三、关于后端使用 OData

1、作为后端开发人员,你有没有碰到过这种前端开发人员,今天让你加一个字段,好,加了,然后打包发布。明天又让你加一个字段。后天突然又说,前两天加的字段,不需要,你会不会有种想喊“操”的冲动?

2、作为后端开发员员,你有没有碰到过这种前端开发人员,今天跟你说接口不够用,要加个 GetUserByName 的方法,明天又说,还得加个 GetUserByEmail 的方法?然后,过了一段时间,你发现接口越来越多,维护的模块越来越痈肿,并且这些接口,你只敢加,不敢删除。因为,你根本不知道这些,有哪个不用的,你跑去问前端,他也回答不出来。所以一些接口哪怕是没用的,也只能永远系统里,直到它生命周期的结束。

如果你也碰到类似于我这种烦恼,使用 OData 也许是一个不错的选择,把查询的权限都开发给前端的开发人员,他爱怎么查就怎么查,都由它去。

四、关于后端使用MVC

我们的系统,使用MVC都是用来处理从前端提交上来的数据的,使用它主要是开发人员都熟悉MVC,然后MVC再调用业务层代码,同时,还需要处理:

1、对提交上来的数据进行验证

2、处理系统的异常,包括对异常进行重新的包装,再传回到客户端,以便于客户端的处理。对异常的信息进行记录。

五、数据访问层

关于数据访问层,在我们的系统里实际是一个 ORM 的包装器(ORM Wrapper),你在对 ORM 裹上一层外衣。目的在于:

1、对数据进行拦截。例如:有些数据,只对某个角色的开发。数据访问层需要对根据过滤条件,然后再结合查询条件,重新生成SQL。

2、对数据假删除的处理。见过很多系统,都是把删除放到业务层来进行的,其实这是不适合的,从业务的角度来说,关心的是删除,在执行删除后,这条数据从我眼前消失就可以了。至真删除还是假删除,这与我无关。数据访问层,要做的就是这工作,它可以数据在真删除与假删除之间进行切换,只要配置一下,就可以把真删除变成假删除(其实就是把Delete操作变成Update操作),使得进行业务开发人员,不用再关心数据的真假删除。

3、对数据进行跟踪、备份。你肯定碰到过这么一种需要,需要记下来,每一次的更新操作的时间,以及更新了些什么内容。对于删除的数据,能够把它还原回来。数据访问层,通过对 ORM进行包装,完全可以记录下每一次更新、删除这些操作,然后记录下来即可。当然,这些需求利用数据提供的功能也是可以实现的,不在讨论的范围内。

这篇文章到此结束,欢迎大家的板砖。

PS:过年的时候,我会把 ALinq 和 Visual Entity 更新到 2013,各位用户就别催更了,最近实在是忙,抽不出时间更新呀。

公司招聘

初级程序员:懂 JQuery、JQuery UI、JQuery Validate、Knockout JS 等JS 框架,略懂 Linq to SQL,能阅读文档,根据文档示例写代码

中级程序员:有阅读上述框架的代码,并根据项目做订制开发

高级程序员:具体很强的编码能力,能解决各种疑难杂症

牛人:能把设计模式、代码玩弄于股掌之间

在找工作的朋友可以私信我。


本文链接:http://www.cnblogs.com/ansiboy/p/3532686.html,转载请注明。

阅读更多内容

OSwatcher on Exadata

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
OSwatcher on Exadata  阅读原文»

OSwatcher作为Oracle官方推荐的OS层面运行状态检测的脚本工具。在Exadata是默认已经安装。

但是Exadata是如何在系统启动后,自动启动OSwatcher呢?我们如何去修改OSwatcher的参数,来调整监控和日志保存的策略呢?

本文正是介绍,从系统启动到OSwatcher运行,中间经历过的脚本调用,以及如何修改OSwatcher参数的。

1. 首先检查rc.local文件,可以发现/etc/rc.d/rc.Oracle.Exadata

# vi /etc/rc.d/rc.local
########### BEGIN DO NOT REMOVE Added by Oracle Exadata ###########
if [ -x /etc/rc.d/rc.Oracle.Exadata ]; then
. /etc/rc.d/rc.Oracle.Exadata <<<<<<<<<<<<<<<<<<<<<<This script will be run automaticlly, when the OS starts
########### END DO NOT REMOVE Added by Oracle Exadata ###########

2. 查看rc.Oracle.Exadata,找到/opt/oracle.cellos/vldrun -all

# vi /etc/rc.d/rc.Oracle.Exadata
# Perform validations step
/opt/oracle.cellos/vldrun -all <<<<<<<<<<<<<<<<<<<<<<This script will be run automaticlly, when the OS starts

3. 检查当前OSwatcher的设定,每15秒收集一次,生成的日志保存168小时(7天),bzip2的压缩模式,最大日志尺寸是3G

# ps -ef | grep OSW
root 15962 1 0 04:00 pts/1 00:00:00 /bin/ksh ./OSWatcher.sh 15 168 bzip2 3
root 15994 15962 0 04:00 pts/1 00:00:00 /bin/ksh ./OSWatcherFM.sh 168 3
root 16272 9529 0 04:00 pts/1 00:00:00 grep OSW

4. 脚本/opt/oracle.cellos/vldrun会调用oswatcher脚本来启动oswatcher

# ls -al /opt/oracle.cellos/validations/init.d/oswatcher
-r-xr-x--- 1 root root 5128 Aug 19 03:39 oswatcher
# chmod 750 oswatcher <<<<<<<<<<<<<<<<<<<<<<<<Change the right, then we can edit it as per our expected.
# ls -al oswatcher
-rwxr-x--- 1 root root 5128 Aug 19 03:39 oswatcher

5. 检查当前oswatcher脚本中的设定,并修改(本次修改将原有的最大保存3G的日志,修改为最大日志尺寸为4G)

(umask 0037; nohup ./startOSW.sh 15 168 bzip2 4 >/var/log/cellos/start_oswatcher.log 2>&1 &)& <<<<<<<<<<<<change this part of the script, will let the script run as per our expected.
# Dont direct logs to startosw.log. It grows too large and fast
# (nohup ./startOSW.sh 15 168 bzip2 3 >/dev/null 2>&1 &)&
popd >/dev/null

6. 停止oswatcher

#/opt/oracle.oswatcher/osw/stopOSW.sh
# ps -ef grep OSW
root 10528 9529 0 03:59 pts/1 00:00:00 grep OSW
7. 手动启动oswatcher
# /opt/oracle.cellos/vldrun -script oswatcher
Logging started to /var/log/cellos/validations.log
Command line is ./validations/bin/vldrun.pl -quiet -script oswatcher
Run validation oswatcher - PASSED
The each boot completed with SUCCESS
如何绘制平台框架的设计图:使用UML工具  阅读原文»

如何绘制平台框架的设计图:使用UML工具

ADT首轮推广大优惠!! 听高老师亲授顶层设计9小时只需450元。抢鲜报名参加架构师思考技术与大数据云平台(顶层)设计法则课程(还赠送线上视频课程),地点:福州、北京、深圳。名额有限,报名请看:http://t.cn/8FqOSGr

wKiom1Lg54SBLZLqAAIx8ojdxOI385.jpgwKiom1LWC47hLcPVAAE4zKFtQbM072.jpg

(高老的新博文出版)

EE EE

相文章:

1. 如何设计平台框架的<未来性>

2. 平台框架(Framework)开发的雕龙之技6招

如何绘制平台框架的设计图:使用UML工具

1. 复习:开始使用UML建模工具(JUDE)

开启JUDE建模工具:

10052330-26bfe5c141a54d679a463bd7425e3c3

点选<File/New>,创建新建模项目:

10052348-2e7b4a6d40c94cbea08fe9295ad60ae

建立新的类图(Class Diagram):

10052405-ffcd02937a99488a8b364b2440b43fd

类图绘图区:

10052419-6dfa1f76d489449187841e8d8a976ba

拉出一个类的图像,并取名为 "汽车":

10052432-9f4d9afac0c042578cbb8e9dae52fc0

2. 开始设计框架

框架设计练习口诀:目前先"不"做轮胎

老子说:"无" 之以为用(有之以为利)

孔子说:知之为知之,"不"知为不知

最伟大的雕刻师罗丹( Musée Rodin)说:把"不"必要的部分去掉。

10052528-25ec140e59bf410f86e3cfee02add74

~~ 先不做轮胎 ~~

10052551-e89c4ff0112046dc915f96f038f8449

相当于:

10052614-04b259626d7e49da8b6edb139e887c8

[g迎光 高ㄌ: http://www.cnblogs.com/myEIT/ ]

3. 应用框架设计范例

10053157-4733c3ba679740a6afbba01a0be6cd7

这个Calculator类的范例代码:

// 引擎部份

class Calculator {

public int run() {

int n;

n = getN();

int sum = 0;

for(int i=0; i<=n; i++) {

sum += i;

}

return sum;

}

private int getN() { return 10; }

}

//------------------------------------------

public class JMain {

public static void main(String[] args) {

Calculator cal = new Calculator();

System.out.println(cal.run());

}

}

~~ 先不做轮胎(先不加糖) ~~

~~ 先做轮毂(先准备砂糖纸包) ~~

10053626-43f751b2de4843d2ba7eba1dfc6a844

范例代码:

// JMain.java

import Engine.Calculator;

public class JMain {

public static void main(String[] args) {

Calculator cal = new Calculator();

System.out.println(cal.run());

}

}

// 引擎部份

package Engine;

import Framework.ICount;

public class Calculator {

ICount ref;

public int run() {

int n;

n = ge

阅读更多内容