15%技术,75%思维和性格
有感于下面这句话(来自AgileChina论坛有关程序员职业规划的讨论(Jacky Huang))。
一个人的成功,15%来自他的专业技术,75%来自于他的思维和性格,10%来自于机遇。
虽然下面Jeff Xiong做了一些批驳,但是我大致同意上面这句话。一方面上面所指的成功因素的比例跟时间分配上的比例完全是不可比的,另一方面,专业技术的发展与性格和思维根本就是分不开的。
有感于下面这句话(来自AgileChina论坛有关程序员职业规划的讨论(Jacky Huang))。
一个人的成功,15%来自他的专业技术,75%来自于他的思维和性格,10%来自于机遇。
虽然下面Jeff Xiong做了一些批驳,但是我大致同意上面这句话。一方面上面所指的成功因素的比例跟时间分配上的比例完全是不可比的,另一方面,专业技术的发展与性格和思维根本就是分不开的。
本文译自 orx tutorials 的对象(object)。phpxer 译,九天雁翎 (博客)修订。最新版本见Orx官方中文Wiki。
由于orx是数据驱动的,我们只需要两行代码创建一个viewport(视口)和一个object。它们的所有属性都定义在配置文件(01_Object.ini)中。
Viewport关联到一个按照配置文件中的信息隐含创建的camera(摄像头)。在配置文件里,你还可以设置它们的大小,坐标,对象的颜色,缩放,旋转,动画,物理属性等等。你甚至无需增加一行代码就可以让任何的配置获得随机值。
在后面的一个示例中我们将看到如何使用一行代码生成复杂的object体系甚至整个 scene(场景)(所有的背景对象和普通对象)。
现在,你可以尝试取消01_Object.ini中某些行的注释,自己尝试一下,然后再继续学习这个教程。完整的选项列表请查看CreationTemplate.ini。
创建一个object是相当简单的。不过,我们首先需确保已经加载了定义了所有object(对象)的属性的配置文件。我们还要通过viewport/camera组合显示创建好的object(对象)。
不要慌张!所有这些都很容易。
在这篇教程中,我们将加载一个位于父目录中的配置文件。正如你可能想到的,在所有的可执行程序都根据其构建类别(mingw, msvs2005, msvs2008, 等)位于各自的子目录的情况下,我们不打算在每个地方重复同样的配置文件。1)
在我们的例子中,加载配置文件使用类似下面这行代码的方式实现:
orxConfig_Load(”../01_Object.ini”);
然后我们创建viewport(视口)。注意 camera的创建是按照为这个viewport预置的配置信息自动完成的。
orxViewport_CreateFromConfig(”Viewport”);
我们差不多完成了。现在我们只需要创建 object!
orxObject_CreateFromConfig(”Object”);
就这样了!object(对象)已经创建,并且由于在camera的视觉平截体(frustum)内,将会被显示出来。
现在,因为我们使用Orx默认的启动器,我们需要申明我们的插件入口点(这里是我们的Init函数)。这可以使用一个宏很容易地实现。
orxSTATUS Init(){...} orxPLUGIN_DECLARE_ENTRY_POINT(Init);
因为orx是数据驱动的,我们不需要手动加载任何数据,例如一个sprite(精灵)。一切都由数据管理器为我们搞定,它会确保sprites不在内存中重复并在其不再使用时自动释放的
如果你查看配置文件,在[Object]这一节,你将看到你可以设定所有的对象属性,例如 graphic (sprite),锚点,颜色,透明度,物理属性,坐标,旋转,缩放,tiling(平铺)(重复),动画,视觉特效,等等。
不要担心,这一切都将在后面的教程中讲到。
现在我们拥有了一个object(对象),我们需要学习如何与之交互。这将我们带入第二个教程:clock.
本文译自 orx tutorials 的首页(main)。phpxer 译,九天雁翎 (博客)修订。最新版本见Orx官方Wiki中文教程。
本教程主要包含Orx的基础和高级教程。Orx 是一个开源、跨平台、轻量级、数据驱动的2D游戏引擎。
这些教程演示了如何设置不同的编程环境(IDE)来运行orx1)。
本节将要介绍orx的基础知识。
你可以从这里下载Windows(mingw, msvs2005 & msvs2008). Linux 和 MacOS X下的可执行文件(包括项目文件,数据和源码)。
前九个基础教程(#1 – #9)使用默认的orx启动程序为基础(underlying layer),这样易于快速测试/制作原型2。
它们被编译成运行时加载(在命令行3) 上 或配置文件中指定它们的名字)的动态连接库。
此外,下面的内容 4) 解释了哪些行为是由默认的orx.exe/orx 启动程序提供的。
这是一个基础的C教程。
由于我们在本教程中使用默认的可执行文件,下面的代码将以插件的方式加载和执行。
另外,一些基础设施有主执行文件为我们处理。
首先,它会加载所有可用的插件和模块。如果你只 需要其中的一些,最好编写你自己的可执行文件而不是插件。这部分包含在后面的教程中。
主执行文件还处理下面这些键盘输入:
* F11 是纵向对齐切换
* Escape 退出
* F12 截屏
* 退格键(Backspace) 重新载入全部配置文件
如果有 orxSYSTEM_EVENT_CLOSE事件发生,程序也会退出。
不过,如果使用 orx作为传统库构建你自己的可执行文件当然也是可以的(也很容易做到)。在教程 #10(使用C++编写) 和 教程 #11 (使用 C编写)。教程 #10 还演示了如何使用orx编写C++代码5)。 同样地,你可以用任何可与C连接的语言编写程序。
在将来的发布中将会为某些常见语言提供封装。如果你想编写这种封装库,为orx做贡献,请通过论坛联系我们。
当前提供的基础教程列表:
下面这些教程由社区创建,它们是了解如何使用 orx的不错的资源,可以在这里寻找到对一些简单问题的解答。
1) 所有的IDE都是免费可以从英特网上下载的。
2) one line for the whole initialization, no main function to write, no loop to handle
用一行代码完成初始化,不需要写main函数, 没有循环要处理
3) 另提供了 .bat/.sh 脚本方便启动所有示例
4) 你将在在所有教程的源文件的开始处看到这些内容
5) Orx本身使用C编写
最近一段时间以来,效率相当地高。 纵观前些年的工作效率中,少有这么利落快速而且不加班的。 回顾这几年,我工作效率的提高主要有下面的几个方面。
专注目标。凡是工作效率高的时间段里,工作目标都很明确。每天一上班,心里就想明白了今天要干什么,每天下班时,想想今天都实现了什么,有什么目标还没有实现。尽管每天早上来了先看看股票新闻,中午饭后看看股票新闻,偶尔下午还打个盹什么的,但工作的时候确实格外专注,丝毫也不会走神。
分离与当前无关的任务/问题。专注目标不是那么容易做到的。印象中以前工作中经常会碰到的问题是工作中遇到的问题。一方面可能得益于基本功的增强,最近虽然也遇到了一些问题,但是都能够通过简单阅读或查找文档,或浏览问题相关的库的源码解决; 另一方面,遇到的问题我总是避繁就简,首先倾向于寻找简单可用可靠的方案,并将心中的疑虑记录下来,集中成一个列表,工作之外翻翻书,系统思考和学习,而不会因为这个问题而叉开思路对相关的内容研究一番。总之,专注当前的任务,把新问题记录下来,回头再专心攻克。
例如我第一次用ibatis,遇到了一些表可以用集合和映射来加强Pojo的OO功能,但是我并不熟悉ibatis的这些特性,并且使用简单的方案也是可行的,于是就直接使用简便方案(在我看来,ibatis主要是将SQL集中起来管理、简化SQL操纵,对OO不感冒)。
工作列表。不论是开发还是设计,一个文本格式的位于源代码存储系统下的待办工作列表与IDE中的TODO项一起构成了专注目标的重要工具。工作目标分解是基本工作步骤,记录工作中产生的新的问题(任务),这样,子问题越来越多,项目中要干的事情越来越丰富。经常性地调整当前工作任务列表,根据重要性对这些任务进行划分。每天都干掉一些问题,经常想着那些最重要的问题。
简单但有迹可寻的设计材料。在思考和工作的过程中,一方面,项目的过程通常比较长,另一方面经验相对丰富的人手头总是有多个事情在并行进行。当时间太长记不清出了或者是切换任务时,经常要查看此前的代码和设计,易于修改以及有历史记录的设计材料对于保持设计思路的完整十分有意义。(设计材料还应该包括重要的图)
正式准确可以依靠的需求文档。这一条无论怎么说都不过分,遇到需求不确定的地方,就去查需求文档。如果没有,就请能够回答的人来回答,委托给他,先去做别的。细想在上一家公司,经常要承担多种角色,甚至连需求也经常没人给一个最终决策,设计开发的时候在模棱两可的需求之间做决定,很烦心。对于一个设计/开发人员而言,需求人员在需求问题方面就是绝对的权威。如果有些建议,可以建议,但一切均以需求/产品人员为准。
单元测试。另一有助于集中精力编码的就是单元测试。单元测试让我集中精力实现当前的功能,需要依赖的其他功能,我总是先生成一个接口,让当前的功能通过测试后再专心去实现该接口。一天下来,一个一个的测试点亮了绿色,一个一个的接口被实现,整天都是十分惬意的。单元测试的另外一个收益就是放心地去重构吧,放心地去做新的特性吧。
无论是在广义的工作方法/工作态度上,还是在针对具体问题的设计/实现上,我认为最重要的个人能力就是化繁为简了。化繁为简是所有工作方法/软件设计的核心。将那些可以砍掉的工作砍掉(最多做个记录),做到尽可能地经济,尽可能地简单。
从工作方法和态度上来讲,真正需要去做的工作才值得去做,大力砍掉那些不应该在当前工作中处理的事情。例如不必要的优化,不必要的扩展性,不必要的性能,不必要的功能,可以不要的技术,不必要的流程,不必要的文档,统统砍掉,一切可以没有的全都不能有。
工作中也可能遇到非关键的难题,通常绕过它们,使用更简单的方案就是了。纠缠于这些不重要的难题,最容易浪费时间。例如,eclipse忽然坏掉了,最好的方法是重装一个; 又如以前我经常自己建一个持续集成服务器,现在我直接养成每次写完代码手工跑一遍的习惯(前提是够用)。简化你的工作!简化!
从设计/实现来讲,最好的方案就是最简单直接、一眼就能看懂的方案。记得刚到一个新的环境,有一个统计任务,既要用到数据库也要用缓存,我做了精细的设计来保证最终一致性,状态流程都很完整,并且使用线程池来并发运行分批处理,最后再合并。虽然控制得很完美很精细,但是流程和结构都很复杂。上头根据此前的项目经验给出了一个更简单的例子,直接将各个任务划分为多个线程,分开存储,到了该统计的时候,冻结数据在所有的分区上做统计。状态砍掉一半,流程缩减一半。
事实上,作为简单直接的一个附带效应,最简单直接的方式,通常性能也最好。
简化问题的能力,是一个人的核心能力。
基本功的内容十分复杂。首先,对整个计算机体系的理解,对操作系统/虚拟机/数据库本质的理解,对语言基础类和库的理解,我觉得是核心基本功。
第二项基本功,就是学习能力。 通过快速阅读核心文档理解核心思想,然后其他的东西总是能从文档中查到就行。细枝末节的东西,即学即用,学过就忘可也。
第三项基本功,就是文档、资料的搜索和收集。
要想在工作中如行云流水,另外一个方面就是避开暂时还不熟悉的技术和工具,不熟悉的东西很难用好,更难用顺畅。尤其是那些纠结复杂、华而不实的技术,不要去碰。这属于简化能力的范畴。
选择工具的核心标准,就是简单朴素可信赖。
文本格式的设计,加上易于修改的图。 我喜欢用一个简单的文本格式来记录设计,随时修改,随时查阅。而附上几幅简单直接的图,经常能够更简单直接地表达更多的内容。
简单的可信赖的工具。我曾经将很长的时间用来构建Maven的环境上,用Maven管理依赖,尤其是跟Eclipse协作时,经常出现诡异。现在我用ant,或者只用Maven,maven不与eclipse纠缠在一起。如果一个工具出几次诡异现象,那就干脆丢掉它。
版本管理工具。 不仅仅源码要由版本管理,整个项目过程的所有知识,全部用版本管理系统管理起来,集中存放。现在我用subversion和git。
最近很多工作在Linux下做,但是因为整个公司的环境是Windows,很多事情也经常要在Windows下处理。于是在Windows XP上用VMware搭建了OpenSUSE,同时使用这两种系统。经过这段时间的使用,觉得OpenSUSE的桌面支持确实是做得不错的,似乎比Ubuntu更加方便简单。但是Ubuntu更流行,很多简单的设置问题,网络上随处可见Ubuntu的解决方案,而SUSE的方案却难觅踪影。
例如,我经常使用VMWare的共享文件夹特性来在Host与Guest之间交换数据,共享文件。 但是在OpenSUSE下,却没有找到合适的方法。最终,不得不求助于Samba。 Samba在OpenSUSE上的安装是很方便的,基本上遵照 How To Samba With openSuse 10.3 And Windows XP 的指导,三两步就完成了。 完毕以后,在Windows XP 下映射一个盘符到 \\GUEST_HOSTNAME\users 就完成了。我完全关闭了Guest上的防火墙,有防火墙反而可能招致麻烦。
而在OpenSUSE上访问Windows XP也很简单,基本上遵照 SDB:Access to Windows Shares 的 Manual Procedure 部分,将Windows XP共享目录加入到 /etc/fstab 中:
1 /dev/sda1 swap swap defaults 0 0 2 /dev/sda2 / ext4 acl,user_xattr 1 1 3 /dev/sda3 /home ext4 acl,user_xattr 1 2 4 proc /proc proc defaults 0 0 5 sysfs /sys sysfs noauto 0 0 6 debugfs /sys/kernel/debug debugfs noauto 0 0 7 usbfs /proc/bus/usb usbfs noauto 0 0 8 devpts /dev/pts devpts mode=0620,gid=5 0 0 9 //x.x.x.x/work /mnt/windows cifs auto,uid=liuz,gid=users,umask=0002,iocharset=utf8,credentials=/etc/winpasswd 0 0
别忘了保护你的密码文件:
chmod 600 /etc/winpassword
特殊之处,是指定了一个 uid=liuz, 将文件的所有者指定为liuz这个用户,方便增删改等操作。有关 uid,gid,umask等的解释如下: (来源)
uid与gid
uid即user identifer,gid即group identifer。设置所有文件的所有者和群组。gid=64,即权限为所有者可读、写,不能执行,群组用户可读、不能写、执行。
umask
umask即user mask,即用户屏蔽。umask=007,即所有文件的权限中,屏蔽其它使用者的读、写、执行权限。
总结一下我使用的这三种方法:
因为特别的原因,需要从Memcached中导出所有的数据。因为Memcached对数据的遍历是明确不支持的,所以必须想歪门邪道的方法。
现在网络上主要有两种思路,一种是通过Memcached提供的stats cachedump命令导出,例如下面这些网址:
以上文章都利用这个命令导出了部分数据。但事实上,cachedump的输出会限制在 2*1024*1024=2M 字节的长度内(Memecahed source: items.c, func: do_item_cachedump),其导出的格式如下所示:
ITEM key990017 [1 b; 1270394155 s] ITEM key990016 [1 b; 1270394155 s] ITEM key990015 [1 b; 1270394155 s] ITEM key990014 [1 b; 1270394155 s]
即使不计算key的长度,每一条数据至少要占掉近三十个字节,2M最多到几万项数据。对于Item数量很大的情况下,这种方法并不能导出全部数据。
下面的地址佐证了这些观点。
第二种思路来自 Twitter infrastructure team 的 Evan Weaver 的 peeping into memcached , 利用 linux 的 ptrace 系统调用导出memcached进程中数据,分析这些数据得到memcached的所有Key。
但是这种方式有其限制的,一方面,编译Memcached时必须编译入调试信息 (参见link); 另一方面,在分析时对内存消耗太大。我们对一个只使用了64M内存、含有76万左右数据项的Memcached进程进行分析,在完成23万左右数据项时,分析进程占用内存的达到1040M,导致虚拟机内存用满,关闭了该进程。
因为我们现在运行的memcached是不带编译符号的,所以放弃了第二种方式。 第一种方式,则只能考虑怎么将slabs中的数据分批导出来。 Memcached 支持一个可选的 slabs reassign
最后,还是利用了第一种方法,每一次导出一批数据以后就从memcached中删除这一批数据,直到全部导出为止。 虽然这种办法很土,但是还是能够应付一次性数据迁移。 当然这是不得以而为之,明智的做法还是在一开始就不要将需要持久化的数据只存在与memcached中。
约一年多前开始使用 vpslink 的 Xen VPS,前不久因为实在是没什么事情做,只放了一个博客,觉得有点不值得,就搬到了 Tektonic 上的 OpenVZ VPS。Tektonic的OpenVZ性能也还可以,但很快就发现网速实在是不行。于是试用了一下fsckvps,速度还不错的,可惜服务不好,尤其是上次事故以后,客服响应很差。另外,发现OpenVZ的虚拟机运行java基本是不可行的,甚至 ant/maven 编译个程序都不行。只能将某些能够修改JVM参数的程序手工做好设置(-Xmx480M)才能运行。
于是开始试用在中国颇为有名的 linode,我比较穷,选择了最便宜的 Linode 360,$19.95/M。 听 blogkid 的 博文 选择了 Fremont 的机房。输入信用卡,vps 很快开通。但是ssh一上去,感觉上很卡,测试了一下速度,速度才 几 K/S。受不了了,在本地测试了一下,发现blogkid 推荐的两个机房(Fremont, Newark)的速度都不行。倒是 Dellas 机房的速度很快,北京联通1M宽带能到140K左右。
于是发了个ticket给linode,很快就回信了,让我重新登录控制面板。果然,控制面板上有了自动迁移机房的按钮。于是开始迁移,速度很慢。第二天早上起来发现迁移完了。试用了一下,速度确实不错。不过很快又遇到了问题,做一个hive的测试,因为内存太少,数据一大进程一多,实在是受不了啊……
于是退了 Linode,申请退款。
最后决定采用Fsckvps+AWS的方案。fsckvps 的价格很便宜,虽然fsckvps最近刚刚出过事情,但是我只有一个博客,数据是每天自动备份的。何况 fsckvps 的网速实在是快(北京联通1M能到180K/S,性价比相当不错,我不到 $10/M(年付)就能拿到 512M (burst 1024M)的内存。 Fsckvps的vps的网速实在是不错,在Google Webmaster Tools中,显示我这个博客的速度faster than %92 of sites:
On average, pages in your site take 1.1 seconds to load (updated on Mar 15, 2010). This is faster than 92% of sites.
但是 fsckvps 的虚拟机是 OpenVZ的,你不能用swap,所以基本上不要指望运行吃内存太猛的程序了,在64位平台上,1024M内存的vps连java –version都跑不了。
而其他需要经常在线的应用,则挪到AWS去跑了。
于是我最后的方案就变成了 FsckVps + AWS. 一个月算起来也不到12$,而且AWS的服务器组集群都行,想咋搞就咋搞。从Fsckvps上操控AWS,实在是太惬意了。当然,AWS对个人的linux操作能力要求是不低的…
云计算虽然是一个热门的概念,但是安全仍然是云计算的七寸。不管吹嘘得有多好,一家宕机就大面积的用户业务停掉这样的事情只需要发生一次,就够热闹的。这不,Google App Engine 宕机了。
(英文:Google App Engine is Down – Backup Data Center Having Problems, 中文: (CSDN新闻)谷歌App Engine宕机:备份数据中心发生故障)
大约在半年前,曾经帮同事解决过一个Commons-dbcp连接池的问题。当时遇到的问题比较诡异,但是其实并不是什么特别复杂的问题,了解DBCP的原理,大部分问题就迎刃而解了。本文主要对连接池的基本原理以及dbcp的实现方式做一个分析,对dbcp的配置参数结合原理做一个简单解释。
JDBC是一套通用的Java语言与多种数据库(文件)通讯的标准API。大部分针对数据库服务器(例如Oracle, MySQL等等)的JDBC实现都是基于TCP/IP连接的客户端-服务器端通讯方式。
当我们需要执行一个数据库操作时,有下面三步:
如果每次处理都要走上面的三步,则应用程序与数据库服务器都要将大量的时间和资源消耗在数据连接的断开与建立上。对于并发较大的系统,建立一次连接然后缓存起来连续使用,直到程序结束等情况下再释放连接,就能够将系统资源集中在对数据库操作的处理上,从而大大提高性能。通常情况下将数据连接的建立和断开委托给一种能够数据库连接池的组件或服务进行管理。而DBCP, C3p0, Proxool等都是常用的开源的连接池组件。
就好像A公司在郊外,他们公司附近没有出租车。如果A公司有人要出去办事,他必须打电话给出租公司订车,用完车后他还要付账报销。 这样每个人出去一趟都必须订车、退车和报销。员工的很多时间白白花费在这上面了。于是A公司跟出租车公司定了一个合同,出租车公司给了他们一个车队。要用车随时去楼下找车队就可以了,用完了也不必结帐,A公司统一跟出租车公司订车和结帐。这个车队就好比连接池,由公司(应用程序)来统一向出租车公司(数据库服务器)订车(建立连接)和退车(关闭连接)。
Commons-dbcp连接池的配置参数比较多,也比较复杂,主要分为
其中Jdbc链接参数、事务处理都跟连接池关系不大,另预处理查询池化参数本文不详细叙述。有关commons-dbcp的详细参数配置信息请参考官方文档。
再用车队来比喻,出租车公司每提供一辆车给A公司,A公司肯定要付出一定费用。这时候维持车队的大小就很重要了,在项目少用车少的时候,车队肯定要减少,不然很多空闲车辆也要付出成本;在项目多用车多的时候,肯定要扩大车队,不然车不够用,车队忙不过来。A公司可以简单地设地两个阀值来动态调节车队中空闲的车辆数目以满足动态需求,一个是最小空闲车辆数(最小空空闲连接数(minIdle),当剩余的空车数目小于该数目时,A公司就向出租车公司请求加入新车。 一个是最大空闲车辆数(maxIdle),当剩余的车大于该数目时,就将刚刚用用完的车还给出租车公司从而减少车队数量。
另外,这家出租车公司可能要为多个客户服务,要考虑能够提供给A公司的最大的车数量,不能超过某个数量(maxActive)。所以A公司想出租车申请新车时首先要看下当前正在用的车辆数目是否超过了这个最大数目,如果没有超过那就直接申请新车,否则可以让申请者(应用程序中执行请求的线程)等待 (maxWait<=0, 无限等待; maxWait>0 当等待时间超过 maxWait时,失败)。
在连接池中,这几个参数是十分重要的,官方的说明如下,是我们调节系统性能时需要认真考虑的值。
| Parameter | Default | Description |
|---|---|---|
| initialSize | 0 |
The initial number of connections that are created when the pool is started. Since: 1.2 线程池启动时初始化的连接数 |
| maxActive | 8 |
The maximum number of active connections that can be allocated from this pool at the same time, or non-positive for no limit. 最大活动连接数,如果非正整数,则不做限制。 |
| maxIdle | 8 |
The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit. 最大空闲连接数。 |
| minIdle | 0 | The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none. 最小空闲连接数。 |
| maxWait | indefinitely |
The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely. (在没有连接可用时)连接池等待一个数据连接可用时的以毫秒计的最大等待时间,超时以后抛出异常, -1 则将无限等待 |
实际上,Dbcp 依赖于 commons-pool 来存储连接对象。 BasicDataSource默认使用GenericObjectPool来管理连接对象。除了请求的线程会在请求和返回连接过程中影响池中连接实例外,另有一个跑着GenericObjectPool.Evictor类型 (implements Runnable) 的实例的线程,也会影响池中的数据库连接。
请继续阅读下一篇:《DBCP连接池(二):Commons-pool的设计》
以前只知道日本右翼历史教科书是怎么篡改历史的,最近读到袁伟时先生的这篇文章,我深受震动,原来我们的历史教科书也有问题。 我们自小接受的历史教育里竟然也有对历史的裁剪、修改,给我们对中国近代历史的认识造成了太严重的影响。影响有多严重,列个提纲各位看官就知道了:

初中历史教科书图片(本图片不代表袁伟时文章中批判的教材,袁文可能指的是别的版本)
再引一段吧:
19、20世纪中国人干了不少“无法无天”的事,义和团事件是其中的典型。值得重视的是不但至今有人把野蛮的行为说成是“革命”,而且到了20世纪90年代,有人竟把主张遵守现行国际条约的观点视为应该严加批判的卖国投降观点!
这篇文章或许是因为其真实而对国人的思想产生强大的震撼,直接导致了刊登该文的杂志主编被撤职,杂志停刊。
2006年1月11日“中国青年报”的《冰点》周刊因刊出袁伟时文章《现代化与历史教科书》[2],因而导致暂时停刊,并引致主编李大同及副主编卢跃刚撤职。3月1日《冰点》复刊,刊登张海鹏的《反帝反封建是近代中国历史的主题》文章批驳上文,并拒刊袁伟时《为何、何时、如何反帝反封建》文章。(来源:维基百科)
也许有的读者会质疑袁伟时的观点,那太好了,希望有人出来反驳一下,真理越辩越明。
下面给出两个版本的链接,内容大致是一样的,只是青年报的版本用语可能更谨慎些。同时放在这里是为了降低因墙影响不能阅读的概率。
文章链接:
最近评论