一、什么是宏函数?通过宏定义的函数是宏函数。如下,编译器在预处理阶段会将Add(x,y)替换为((x)*(y))#defineAdd(x,y)((x)*(y))#defineAdd(x,y)((x)*(y))intmain(){inta=10;intb=20;intd=10;intc=Add(a+d,b)*2;cout<
地推话术,如何应对地推过程中家长的拒绝
校师学
相信校长们在做地推的时候经常遇到这种情况:市场专员反馈家长不接单,咨询师反馈难以邀约这些家长上门,校区地推疲软,招生难。为什么?仅从地推层面分析,一方面因为家长受到的信息轰炸越来越多,对信息越来越“免疫”;而另一方面地推人员的专业能力和营销话术没有提高,无法应对家长的拒绝,对有意向的家长也不知如何跟进,眼睁睁看着家长走远;对于家长的疑问,更不知道如何有技巧地回答,机会白白流失。由于回答没技巧和专业
谢谢你们,爱你们!
鹿游儿
昨天家人去泡温泉,二个孩子也带着去,出发前一晚,匆匆下班,赶回家和孩子一起收拾。饭后,我拿出笔和本子(上次去澳门时做手帐的本子)写下了1\2\3\4\5\6\7\8\9,让后让小壹去思考,带什么出发去旅游呢?她在对应的数字旁边画上了,泳衣、泳圈、肖恩、内衣内裤、tapuy、拖鞋……画完后,就让她自己对着这个本子,将要带的,一一带上,没想到这次带的书还是这本《便便工厂》(晚上姑婆发照片过来,妹妹累得
C语言如何定义宏函数?
小九格物
c语言
在C语言中,宏函数是通过预处理器定义的,它在编译之前替换代码中的宏调用。宏函数可以模拟函数的行为,但它们不是真正的函数,因为它们在编译时不会进行类型检查,也不会分配存储空间。宏函数的定义通常使用#define指令,后面跟着宏的名称和参数列表,以及宏展开后的代码。宏函数的定义方式:1.基本宏函数:这是最简单的宏函数形式,它直接定义一个表达式。#defineSQUARE(x)((x)*(x))2.带参
微服务下功能权限与数据权限的设计与实现
nbsaas-boot
微服务java架构
在微服务架构下,系统的功能权限和数据权限控制显得尤为重要。随着系统规模的扩大和微服务数量的增加,如何保证不同用户和服务之间的访问权限准确、细粒度地控制,成为设计安全策略的关键。本文将讨论如何在微服务体系中设计和实现功能权限与数据权限控制。1.功能权限与数据权限的定义功能权限:指用户或系统角色对特定功能的访问权限。通常是某个用户角色能否执行某个操作,比如查看订单、创建订单、修改用户资料等。数据权限:
理解Gunicorn:Python WSGI服务器的基石
范范0825
ipythonlinux运维
理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico
小丽成长记(四十三)
玲玲54321
小丽发现,即使她好不容易调整好自己的心态下一秒总会有不确定的伤脑筋的事出现,一个接一个的问题,人生就没有停下的时候,小问题不断出现。不过她今天看的书,她接受了人生就是不确定的,厉害的人就是不断创造确定性,在Ta的领域比别人多的确定性就能让自己脱颖而出,显示价值从而获得的比别人多的利益。正是这样的原因,因为从前修炼自己太少,使得她现在在人生道路上打怪起来困难重重,她似乎永远摆脱不了那种无力感,有种习
学点心理知识,呵护孩子健康
静候花开_7090
昨天听了华中师范大学教育管理学系副教授张玲老师的《哪里才是学生心理健康的最后庇护所,超越教育与技术的思考》的讲座。今天又重新学习了一遍,收获匪浅。张玲博士也注意到了当今社会上的孩子由于心理问题导致的自残、自杀及伤害他人等恶性事件。她向我们普及了一个重要的命题,她说心理健康的一些基本命题,我们与我们通常的一些教育命题是不同的,她还举了几个例子,让我们明白我们原来以为的健康并非心理学上的健康。比如如果
2021年12月19日,春蕾教育集团团建活动感受——黄晓丹
黄错错加油
感受:1.从陌生到熟悉的过程。游戏环节让我们在轻松的氛围中得到了锻炼,也增长了不少知识。2.游戏过程中,我们贡献的是个人力量,展现的是团队的力量。它磨合的往往不止是工作的熟悉,更是观念上契合度的贴近。3.这和工作是一样的道理。在各自的岗位上,每个人摆正自己的位置、各司其职充分发挥才能,并团结一致劲往一处使,才能实现最大的成功。新知:1.团队精神需要不断地创新。过去,人们把创新看作是冒风险,现在人们
Cell Insight | 单细胞测序技术又一新发现,可用于HIV-1和Mtb共感染个体诊断
尐尐呅
结核病是艾滋病合并其他疾病中导致患者死亡的主要原因。其中结核病由结核分枝杆菌(Mycobacteriumtuberculosis,Mtb)感染引起,获得性免疫缺陷综合症(艾滋病)由人免疫缺陷病毒(Humanimmunodeficiencyvirustype1,HIV-1)感染引起。国家感染性疾病临床医学研究中心/深圳市第三人民医院张国良团队携手深圳华大生命科学研究院吴靓团队,共同研究得出单细胞测序
c++ 的iostream 和 c++的stdio的区别和联系
黄卷青灯77
c++算法开发语言iostreamstdio
在C++中,iostream和C语言的stdio.h都是用于处理输入输出的库,但它们在设计、用法和功能上有许多不同。以下是两者的区别和联系:区别1.编程风格iostream(C++风格):C++标准库中的输入输出流类库,支持面向对象的输入输出操作。典型用法是cin(输入)和cout(输出),使用>操作符来处理数据。更加类型安全,支持用户自定义类型的输入输出。#includeintmain(){in
瑶池防线
谜影梦蝶
冥华虽然逃过了影梦的军队,但他是一个忠臣,他选择上报战况。败给影梦后成逃兵,高层亡尔还活着,七重天失守......随便一条,即可处死冥华。冥华自然是知道以仙界高层的习性此信一发自己必死无疑,但他还选择上报实情,因为责任。同样此信送到仙宫后,知道此事的人,大多数人都认定冥华要完了,所以上到仙界高层,下到扫大街的,包括冥华自己,全都准备好迎接冥华之死。如果仙界现在还属于两方之争的话,冥华必死无疑。然而
爬山后遗症
璃绛
爬山,攀登,一步一步走向制高点,是一种挑战。成功抵达是一种无法言语的快乐,在山顶吹吹风,看看风景,这是从未有过的体验。然而,爬山一时爽,下山腿打颤,颠簸的路,一路向下走,腿部力量不够,走起来抖到不行,停不下来了!第二天必定腿疼,浑身酸痛,坐立难安!
knob UI插件使用
换个号韩国红果果
JavaScriptjsonpknob
图形是用canvas绘制的
js代码
var paras = {
max:800,
min:100,
skin:'tron',//button type
thickness:.3,//button width
width:'200',//define canvas width.,canvas height
displayInput:'tr
Android+Jquery Mobile学习系列(5)-SQLite数据库
白糖_
JQuery Mobile
目录导航
SQLite是轻量级的、嵌入式的、关系型数据库,目前已经在iPhone、Android等手机系统中使用,SQLite可移植性好,很容易使用,很小,高效而且可靠。
因为Android已经集成了SQLite,所以开发人员无需引入任何JAR包,而且Android也针对SQLite封装了专属的API,调用起来非常快捷方便。
我也是第一次接触S
impala-2.1.2-CDH5.3.2
dayutianfei
impala
最近在整理impala编译的东西,简单记录几个要点:
根据官网的信息(https://github.com/cloudera/Impala/wiki/How-to-build-Impala):
1. 首次编译impala,推荐使用命令:
${IMPALA_HOME}/buildall.sh -skiptests -build_shared_libs -format
2.仅编译BE
${I
求二进制数中1的个数
周凡杨
java算法二进制
解法一:
对于一个正整数如果是偶数,该数的二进制数的最后一位是 0 ,反之若是奇数,则该数的二进制数的最后一位是 1 。因此,可以考虑利用位移、判断奇偶来实现。
public int bitCount(int x){
int count = 0;
while(x!=0){
if(x%2!=0){ /
spring中hibernate及事务配置
g21121
Hibernate
hibernate的sessionFactory配置:
<!-- hibernate sessionFactory配置 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<
log4j.properties 使用
510888780
log4j
log4j.properties 使用
一.参数意义说明
输出级别的种类
ERROR、WARN、INFO、DEBUG
ERROR 为严重错误 主要是程序的错误
WARN 为一般警告,比如session丢失
INFO 为一般要显示的信息,比如登录登出
DEBUG 为程序的调试信息
配置日志信息输出目的地
log4j.appender.appenderName = fully.qua
Spring mvc-jfreeChart柱图(2)
布衣凌宇
jfreechart
上一篇中生成的图是静态的,这篇将按条件进行搜索,并统计成图表,左面为统计图,右面显示搜索出的结果。
第一步:导包
第二步;配置web.xml(上一篇有代码)
建BarRenderer类用于柱子颜色
import java.awt.Color;
import java.awt.Paint;
import org.jfree.chart.renderer.category.BarR
我的spring学习笔记14-容器扩展点之PropertyPlaceholderConfigurer
aijuans
Spring3
PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是BeanFactoryPostProcessor接口的一个实现。关于BeanFactoryPostProcessor和BeanPostProcessor类似。我会在其他地方介绍。
PropertyPlaceholderConfigurer可以将上下文(配置文件)中的属性值放在另一个单独的标准java
maven 之 cobertura 简单使用
antlove
maventestunitcoberturareport
1. 创建一个maven项目
2. 创建com.CoberturaStart.java
package com;
public class CoberturaStart {
public void helloEveryone(){
System.out.println("=================================================
程序的执行顺序
百合不是茶
JAVA执行顺序
刚在看java核心技术时发现对java的执行顺序不是很明白了,百度一下也没有找到适合自己的资料,所以就简单的回顾一下吧
代码如下;
经典的程序执行面试题
//关于程序执行的顺序
//例如:
//定义一个基类
public class A(){
public A(
设置session失效的几种方法
bijian1013
web.xmlsession失效监听器
在系统登录后,都会设置一个当前session失效的时间,以确保在用户长时间不与服务器交互,自动退出登录,销毁session。具体设置很简单,方法有三种:(1)在主页面或者公共页面中加入:session.setMaxInactiveInterval(900);参数900单位是秒,即在没有活动15分钟后,session将失效。这里要注意这个session设置的时间是根据服务器来计算的,而不是客户端。所
java jvm常用命令工具
bijian1013
javajvm
一.概述
程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统日志、堆dump文件、线程dump文件、GC日志等。通过虚拟机监控和诊断工具可以帮忙我们快速获取、分析需要的数据,进而提高问题解决速度。 本文将介绍虚拟机常用监控和问题诊断命令工具的使用方法,主要包含以下工具:
&nbs
【Spring框架一】Spring常用注解之Autowired和Resource注解
bit1129
Spring常用注解
Spring自从2.0引入注解的方式取代XML配置的方式来做IOC之后,对Spring一些常用注解的含义行为一直处于比较模糊的状态,写几篇总结下Spring常用的注解。本篇包含的注解有如下几个:
Autowired
Resource
Component
Service
Controller
Transactional
根据它们的功能、目的,可以分为三组,Autow
mysql 操作遇到safe update mode问题
bitray
update
我并不知道出现这个问题的实际原理,只是通过其他朋友的博客,文章得知的一个解决方案,目前先记录一个解决方法,未来要是真了解以后,还会继续补全.
在mysql5中有一个safe update mode,这个模式让sql操作更加安全,据说要求有where条件,防止全表更新操作.如果必须要进行全表操作,我们可以执行
SET
nginx_perl试用
ronin47
nginx_perl试用
因为空闲时间比较多,所以在CPAN上乱翻,看到了nginx_perl这个项目(原名Nginx::Engine),现在托管在github.com上。地址见:https://github.com/zzzcpan/nginx-perl
这个模块的目的,是在nginx内置官方perl模块的基础上,实现一系列异步非阻塞的api。用connector/writer/reader完成类似proxy的功能(这里
java-63-在字符串中删除特定的字符
bylijinnan
java
public class DeleteSpecificChars {
/**
* Q 63 在字符串中删除特定的字符
* 输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
* 例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
*/
public static voi
EffectiveJava--创建和销毁对象
ccii
创建和销毁对象
本章内容:
1. 考虑用静态工厂方法代替构造器
2. 遇到多个构造器参数时要考虑用构建器(Builder模式)
3. 用私有构造器或者枚举类型强化Singleton属性
4. 通过私有构造器强化不可实例化的能力
5. 避免创建不必要的对象
6. 消除过期的对象引用
7. 避免使用终结方法
1. 考虑用静态工厂方法代替构造器
类可以通过
[宇宙时代]四边形理论与光速飞行
comsci
从四边形理论来推论 为什么光子飞船必须获得星光信号才能够进行光速飞行?
一组星体组成星座 向空间辐射一组由复杂星光信号组成的辐射频带,按照四边形-频率假说 一组频率就代表一个时空的入口
那么这种由星光信号组成的辐射频带就代表由这些星体所控制的时空通道,该时空通道在三维空间的投影是一
ubuntu server下python脚本迁移数据
cywhoyi
pythonKettlepymysqlcx_Oracleubuntu server
因为是在Ubuntu下,所以安装python、pip、pymysql等都极其方便,sudo apt-get install pymysql,
但是在安装cx_Oracle(连接oracle的模块)出现许多问题,查阅相关资料,发现这边文章能够帮我解决,希望大家少走点弯路。http://www.tbdazhe.com/archives/602
1.安装python
2.安装pip、pymysql
Ajax正确但是请求不到值解决方案
dashuaifu
Ajaxasync
Ajax正确但是请求不到值解决方案
解决方案:1 . async: false , 2. 设置延时执行js里的ajax或者延时后台java方法!!!!!!!
例如:
$.ajax({ &
windows安装配置php+memcached
dcj3sjt126com
PHPInstallmemcache
Windows下Memcached的安装配置方法
1、将第一个包解压放某个盘下面,比如在c:\memcached。
2、在终端(也即cmd命令界面)下输入 'c:\memcached\memcached.exe -d install' 安装。
3、再输入: 'c:\memcached\memcached.exe -d start' 启动。(需要注意的: 以后memcached将作为windo
iOS开发学习路径的一些建议
dcj3sjt126com
ios
iOS论坛里有朋友要求回答帖子,帖子的标题是: 想学IOS开发高阶一点的东西,从何开始,然后我吧啦吧啦回答写了很多。既然敲了那么多字,我就把我写的回复也贴到博客里来分享,希望能对大家有帮助。欢迎大家也到帖子里讨论和分享,地址:http://bbs.csdn.net/topics/390920759
下面是我回复的内容:
结合自己情况聊下iOS学习建议,
Javascript闭包概念
fanfanlovey
JavaScript闭包
1.参考资料
http://www.jb51.net/article/24101.htm
http://blog.csdn.net/yn49782026/article/details/8549462
2.内容概述
要理解闭包,首先需要理解变量作用域问题
内部函数可以饮用外面全局变量
var n=999;
functio
yum安装mysql5.6
haisheng
mysql
1、安装http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
2、yum install mysql
3、yum install mysql-server
4、vi /etc/my.cnf 添加character_set_server=utf8
po/bo/vo/dao/pojo的详介
IT_zhlp80
javaBOVODAOPOJOpo
JAVA几种对象的解释
PO:persistant object持久对象,可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作.
VO:value object值对象。通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可
java设计模式
kerryg
java设计模式
设计模式的分类:
一、 设计模式总体分为三大类:
1、创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
2、结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
3、行为型模式(11种):策略模式,模版方法模式,观察者模式,迭代子模式,责任链模式,命令模式,备忘录模式,状态模式,访问者
[1]CXF3.1整合Spring开发webservice——helloworld篇
木头.java
springwebserviceCXF
Spring 版本3.2.10
CXF 版本3.1.1
项目采用MAVEN组织依赖jar
我这里是有parent的pom,为了简洁明了,我直接把所有的依赖都列一起了,所以都没version,反正上面已经写了版本
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht
Google 工程师亲授:菜鸟开发者一定要投资的十大目标
qindongliang1922
工作感悟人生
身为软件开发者,有什么是一定得投资的? Google 软件工程师 Emanuel Saringan 整理了十项他认为必要的投资,第一项就是身体健康,英文与数学也都是必备能力吗?来看看他怎么说。(以下文字以作者第一人称撰写)) 你的健康 无疑地,软件开发者是世界上最久坐不动的职业之一。 每天连坐八到十六小时,休息时间只有一点点,绝对会让你的鲔鱼肚肆无忌惮的生长。肥胖容易扩大罹患其他疾病的风险,
linux打开最大文件数量1,048,576
tianzhihehe
clinux
File descriptors are represented by the C int type. Not using a special type is often considered odd, but is, historically, the Unix way. Each Linux process has a maximum number of files th
java语言中PO、VO、DAO、BO、POJO几种对象的解释
衞酆夼
javaVOBOPOJOpo
PO:persistant object持久对象
最形象的理解就是一个PO就是数据库中的一条记录。好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作。
BO:business object业务对象
封装业务逻辑的java对象
最近两年 C++又有很多人出来追捧,并且追捧者充满了各种优越感,似乎不写 C++你就一辈子是低端程序员了,面对这种现象,要不要出来适时的黑一下 C++呢?呵呵呵。
咱们要有点娱乐精神,关于 C++的笑话数都数不清:
笑话:C++是一门不吉祥的语言,据说波音公司之前用ADA为飞机硬件编程,一直用的好好的,后来招聘了一伙大学生,学生们说我靠还在用这么落后的语言,然后换成C++重构后飞机就坠毁了。
笑话:什么是C++程序员呢?就是本来10行写得完的程序,他非要用30行来完成,并自称“封装”,但每每到第二个项目的时候却将80%打破重写,并美其名曰 “重构”。
笑话:C容易擦枪走火打到自己的脚,用C++虽然不容易,但一旦走火,就会把你整条腿给炸飞了。
笑话:同时学习两年 Java的程序员在一起讨论的是面向对象和设计模式,而同时学习两年 C++的程序员,在一起讨论的是 template和各种语言规范到底怎么回事情。
笑话:教别人学 C++的人都挣大钱了,而很多真正用 C++的人,都死的很惨。
笑话:C++有太多地方可以让一个人表现自己“很聪明”,所以使用C++越久的人,约觉得自己“很聪明”结果步入陷阱都不知道,掉坑里了还觉得估计是自己没学好 C++。
笑话:好多写了十多年 C++程序的人,至今说不清楚 C++到底有多少规范,至今仍然时不时的落入某些坑中。
笑话:很多认为 C++方便跨平台的人,实际编写跨平台代码时,都会发现自己难找到两个支持相同标准的 C++编译器。
—————
Q:那 C++为什么还能看到那么多粉丝呢?
A:其实是因为 Windows,因为 Windows的兴起带动了 C++,C++本来就是一门只适合开发 GUI的语言。
Q:为何 C++只适合开发 GUI呢?
A:你看 Unix下没有 GUI,为啥清一色的 C呀?所有的系统级问题都能在 C里找到成熟的解决方案,应用级问题都能用其他高级语言很好地解决,哪里有 C++什么事情呀?
Q:你强词夺理,Unix下也有 C++的项目呀。
A:有,没错,你任然可以用任何语言编写任何糟糕的代码。
Q:别瞎扯了,你都在说些什么?连C++和 Windows 都扯到一起去了。
A:回想下当年的情景,一个大牛在教一群初学者如何编程。一边开发一边指着屏幕上说,你看,这是一个 Button,我们可以用一个对象来描述它,那是一个 panel我们也可以用一个对象来描述它,并且你们有没有发现,其实 Button和 Panel是有血缘关系的,你们看。。。这样就出来了。。。。下面的学生以前都是学着学校落后的教材,有些甚至还在用 turboc的 bgi库来画一些点和圆。哪里见过这么这么华丽的 Windows 界面呀。大牛说的话,象金科玉律一样的铭刻在自己幼小的心理。一边学着 Windows,一边发现,果然,他们都需要一个基类,果然,他们是兄弟关系,共同包含一些基本属性,可以放到基类去。他们越用越爽,潜意识里觉得因为 C++这么顺利的帮他们解决那么多界面问题,那看来 C++可以帮他们解决一切问题了。于是开发完界面以后,他们继续开发,当他们碰到各种设计问题时,反而认为肯定自己没有用好 C++。于是强迫自己用下去,然后就完蛋了。
(点击 more展开)
—————
关于 C++的笑话我有一箩筐,各位 C++粉用不着对号入座。言归正传,为什么要黑 C++呢?谈不上黑不黑,我从94年开始使用 C++(先前是 C 和 Pascal),一路看着 C++成长壮大,用 C++写过的代码,加起来应该超过 10MB了吧,C++的各种宝典我也都读过,一直到 2004年开始切回 C,主要原因是发现很多没法用 C++思路继续解决下去的问题,或者说用 C++思路解决下去会很糟糕的问题。
那时候(2004-2005)正是 C++满天飞的时候,言必称 C++,用必用模版,我跳出来说你们醒醒吧,别过火了,这个世界并不是都是抽象数据结构和算法就可以描述清楚的。于是很多人激动的跳出来说:“你没领会到 C++精髓,你根本都不会用 C++”。我问他们:“语言是用来解决问题的,如果一个语言学了三四年都会经常掉沟里,算好语言么?如果编写十多年 C++的程序员都很难掌握得了,这算好语言么”。他们又说:“语言是死的,人是活的”。
我记得当时一位国内 C++大牛,为了纠正我的 “错误观点”,给我看过他写的一套十分强大的库,我打开一看,倒吸了一口冷气,全部是 .h文件。我只能回他三个字:“你牛逼”。当然这是一个极端的例子,那家伙后来终于也开始把 .h里面的东西逐步挪到 .cpp里面了,这是好事。
当时和云风在一家公司,2004年新人培训时,他给新人布置了一个实现内存分配器的作业,批改作业的时候,他经常边看边问人家,“不够C++呀,你能不能百分之百OOP?”,“1%的 C都不要留”。我当时在公司内部邮件列表里面发过关于 C++的问题,大部分人都表示:“你看没有C++我们怎么写3D引擎呢?”。我跟他们讲:“John Carmack直到 Quake3都还在用着 ANSI C,后来因为不得不支持 D3D,改用 C++了。为啥 C不能写 3D引擎了?”。他们告诉我:“你看,Point,就是个对象,Matrix也是个对象,那么多 Vector的代数计算,用 C++的算术重载是多么美妙的事情,三维世界就是对象的世界。”。
确实当时客户端 GUI的话,只有 C++,图形引擎也只有 C++,这两个正是C++最强的地方,所以我也没和他们争辩,强迫他们承认 C也可以很漂亮的写图形,而且C写的可以写的很优雅。我又不是闲着没事情,何必去质疑人家的核心价值观呢,呵呵。当年我正在接手一个 C++项目,代码超过 800KB,每次崩溃都需要花费很长时间去定位,项目中大量的前后依赖,改一个地方,前后要看好几处,一处遗漏,整个系统就傻逼了。我开始重构后,画了两个星期,将性能敏感的核心部分剥离出来用 C实现(代码量仅 200KB),然后导出 Python接口,用Python来完成剩下的部分,整个脚本层代码量只有 150KB。整个世界清爽了,整个 C++项目原来的工期为 2个程序员四个月,我一个人重构的时间加起来就 1.5个月,而且代码量比远来少了两倍还多,各种奇特的 BUG也一扫而尽。我看看左边的 800KB一团乱麻的 C++代码,再看看右边整洁的 300多 KB 纯 C + Python,琢磨着,这个项目干嘛不一开始就这么做?
跨语言接口
现代项目开发,不但需要更高的性能,而且需要更强大的语言描述能力。而 C++正处在一个尴尬的地方,比底层,它不如 C能够精确的控制内存和硬件,各种隐式构造让你防不胜防;比描述能力,比快速业务开发和错误定位,它又赶不上 Python, Ruby, Lua等动态语言,处于东线和西线同时遭受挤压和蚕食的地步。
很快,2006-2007年左右,其他项目组各种滥用 C++的问题开始显现出来:当时脚本化已经在工程实践中获得极大的成功,然而某些项目一方面又要追求 100%的 C++,另一方面又需要对脚本导出接口,他们发现问题了,不知道该怎么把大量的 C++基础库和接口导给 Lua。
C的接口有各种方便的方式导给脚本,然而整个项目由一群从来就不消于使用脚本的cpp大牛开发出来,当他们要吧cpp类导出接口给脚本时,他们设计了一套牛逼的系统,lua自动生成机器码,去调用c++的各种类,没错,就是c++版本的cffi或者ctypes。他为调用vc的类写了一套机器码生产,又为调用gcc的类写了一套代码生成。那位cpp大牛写完后四处炫耀他的成果,后来他离职了,项目上线一而再再而三的出现无可查证的问题,后来云风去支援那个项目组,这套盘根错节的c++项目,这套盘大的代码自生成系统深深的把他给恶心到了。后来众所周知云风开始反C++,倡导回归C了,不知道是否和这个项目有关系。
于是发现个有趣的现象,但凡善于使用脚本来提高工程效率的人,基本都是C加动态语言解决大部分问题(除了gui和图形),但凡认为c++统治宇宙的人很多都是从来没使用过脚本或者用了还不知道该怎样去用的人。
凭借这样的方法,我们的产品同竞争对手比拼时,同样一个功能,同样的人力配置,竞争对手用纯C++要开发三月,我们一个月就弄出来了,同样的时间,对手只能试错一次,我们可以试错三次。后来,据我们招聘过来的同事说,竞争对手也开始逐步降低 C++的比例,增加 java的比例了,这是好事,大家都在进步嘛。
ABI的尴尬
ABI级别的 C++接口从来没有标准化过,以类为接口会引入很多隐藏问题,比如内存问题,一个类在一个库里面实例化的,如果再另外一个库里面释放它们就有很多问题,因为两个动态库可能内存管理系统是不一样的。你用这里的 allocator分配一块内存,又用那里的 allocator去释放,不出问题才怪。很多解决方法是加一个 Release 方法(比如 DX),告诉外面的人,用完的时候不要去 delete,而是要调用 Release。
项目写大了各个模块隔离成动态库是很正常的,而各种第三方库和自己写的库为追求高性能引入特定的内存管理机制也是很正常的。很多人不注意该调用release的地方错写成delete就掉沟里去了。更有胜者跨 ABI定义了很多inline方法的类,结果各种隐式构造和析构其实在这个库里生成,那个库里被析构,乱成一团乱麻。C就清晰很多,构造你就调用fopen,析构你就fclose,没有任何歧义。其实C++的矛盾在于一方面承认作为系统级语言内存管理应该交给用户决定,一方面自己却又定义很多不受用户控制的内存操作行为。所以跨 ABI层的c++标准迟迟无法被定义出来,不是因为多态 abi复杂,而是因为语言逻辑出现了相互矛盾。为了弥补这个矛盾,C++引入了operator new,delete,这new/delete重载是一个补丁并没从逻辑上让语言变得完备,它的出现,进一步将使用者拖入bug的深渊。
其实今天我们回过头去看这个问题,能发现两个基本原则:跨abi的级别上引入不可控的内存机制从语言上是有问题的,只能要靠开发者约定各种灵巧的基类和约定开发规范来解决,这个问题在语言层是解决不了的;其次你既然定义了各种隐式构造和析构,就该像java或者动态语言一样彻底接管内存,不允许用户再自定义任何内存管理方法,而不是一方面作为系统极语言要给用户控制的自由,一方面自己又要抢着和用户一起控制。
因此对象层 ABI接口迟迟无法标准化。而纯 C的 ABI不但可以轻松的跨动态库还能轻松的和汇编及各类语言融合,不是因为C设计多好,而是C作为系统层语言没有去管它不该管的东西。当年讨论到这个话题时 C++大牛们又开始重复那几句金科玉律来反驳我:“语言只是招式,你把内功练好,就能做到无招胜有招,拿起草来都可以当剑使,C++虽然有很多坑,你把设计做好不那么用不就行了”。我说:本来应该在语言层解决好的事情,由于语言逻辑不完备,将大量问题抛给开发者去解决极大的增加了开发者的思维负担,就像破屋上表浆糊一样。你金庸看多了吧,武术再高,当你拿到一把枪发现子弹不一定往前射,偶尔还会往后射时,请问你是该专心打敌人呢?还是时刻要提防自己的子弹射向自己?
系统层的挫败
C++遭受挫败是进军嵌入式和操作系统这样靠近硬件层的东西。大家觉得宇宙级别的编程语言,自然能够胜任一切任务,很快发现几个问题:
当然,说道这里很多人又说,“C++本来就是 C的超集,特定的地方你完全可以按照C的写法来做呀。没人强迫你构造类或者使用异常呀”,没错,按 Linus的说法:“想要用 C++写出系统级的优秀的可移植和高效的代码,最终还是会限于使用 C本身提供的功能,而这些功能 C都已经完美提供了,所以系统层使用 C的意义就在于在语言层排除 C++的其他特性的干扰”。
很多人都记得 Linus在 2007年因为有人问 Git为什么不用 C++开发炮轰过一次C++。事实上2004年 C++如日中天的时候,有人问 Linux内核为何不用 C++开发,他就炮轰过一次了:
C++粉丝们在C++最火热的时候试图将 C++引入系统层开发,但是从来没有成功过。所以不管是嵌入式,还是操作系统,在靠近硬件底层的开发中,都是清一色的 C代码,完全没有 C++的立足之地。
应用层的反思
STL出来后,给人一种 C++可以方便开发应用层逻辑的错觉。由于很多语言层不严密的事情,让STL来以补丁的方式完成,于是很多以为可以象写 java一样写 C++的初学者落入了一个个的坑中。比如 list.size(),在 Windows下vc的 stl是保存了 list的长度的,size()直接 O(1)返回该变量,而在gcc的 stl中,没有保存 list长度,size()将搜索所有节点,O(n)的速度返回。
由于语言层不支持字符串,导致 std::string实现十分不统一,你拷贝构造一个字符串,有的实现是引用,才用 copy-on-write的方法引用。有的地方又是 new,有的实现又是用的内存池,有的实现线程安全,有的实现线程不安全,你完全没法说出同一个语句后面到底做了些什么(见孟岩的《Linux之父话糙理不糙》)。
再比如说我想使用 hash_map,为了跨平台(当你真正编写跨平台代码时,你很难决定目标编译器和他们的版本,想用也用不了 unordered_map),我很难指出一种唯一声明 hash_map的方法,为了保证在不同的编译器下正常的使用 hash_map,你不得不写成这样:
如果有更好的跨平台写法,麻烦告诉我一下,实在是看不下去了。一个基础容器都让人用的那么辛苦,使得很多 C++程序员成天都在思考各种规范,没时间真正思考下程序设计。
由于语言层要兼容 C,又不肯象 C一样只做好系统层的工作,导致当 C++涉足应用层时,没法接管内存管理,没法支持语言层字符串,没法实现语言层基础容器。所以需要借助一些 stl之类的东西来提供便利,但 stl本身又是充满各种坑的。且不说内存占用大,程序体积大等问题,当编译速度就够呛了。所以为什么 C++下面大家乐意重复造轮子,实现各种基本容器和字符串,导致几乎每个不同的 C++项目,都有自己特定的字符串实现。就是因为大家踩了坑了,才开始觉得需要自己来控制这些细节。stl的出发点是好的,但是只能简单小程序里面随便用一下,真是大项目用,stl就容易把人带沟里了,所以很多大点的 C++项目都是自己实现一套类似 STL的东西,这难道不是违背了 stl设计的初衷了么?
语言层的缺失,让大家为了满足业务开发的快速迭代的需求,创造了很多很基础的设计灵巧的基类,来提供类似垃圾回收,引用计数,copy-on-write,delegate,等数不胜数的功能。每个项目都有一系列 BaseObject 之类的基础类,这样就引入一个误区,两年后你再来看你的代码,发现某个 BaseObject不满足需求了,或者你和另外一个项目 merge代码时,需要合并一些根本属性。图形和GUI这些万年不变的模型还好,应用类开发千变万化,一旦这些设计灵巧的基类不再适应项目发展时,往往面临着全面调整的代价。
打开一个个 C++大牛们 blog,很多地方在教你 std::string的原理,需要注意的事项。map的限制,vector的原理,教你如何实现一个 string。这就叫 “心智负担”,分散你的注意力,这是其他语言里从来见不到的现象。战士不研究怎么上前线杀敌,天天在琢磨抢和炮的原理,成天在思考怎么用枪不会走火,用炮不会炸到自己,这战还怎么打?
所以此后几年,越来越多的人开始反思前两年C++过热所带来的问题,比如高性能网络库 ZeroMQ作者 Martin Sustrik 的:《为什么我希望用C而不是C++来实现ZeroMQ》,比如云风的《云风的 BLOG: C 的回归》,比如引起热议的《Why C++ Is Not "Back"》。
全面被代替
2008年以后,行业竞争越来越激烈,正当大家一边苦恼如何提高开发效率,一边掉到C++的各种坑里的时候,越来越多的应用开发方案涌现出来,他们都能很好的代替 C++。各行各业的开发者逐步相见恨晚的发现了各种更加优秀的方案:需要底层控制追求性能的设计,大家退回到 C;而需要快速迭代的东西大家找到各种动态语言;介于性能和开发速度之间的,有java,知乎上好像很多黑java的,语言是有不足,但是比起C++好很多,没那么多坑,真正考虑面向对象,真正让人把心思放在设计上。所以再黑也不能挡住 java在 tiobe上和 C语言不是第一就是第二的事实,再黑也挡不住 java在云计算,分布式领域的卓越贡献。
所以2005年以后,C++处在一个全面被代替的过程中:
可以看出,即便 C++的老本行,GUI和图形(确实也还存在一些短期内 C++无法替代的领域,就像交易系统里还有 COBOL一样),这年头也面临的越来越多的挑战,比如新发布的 Rust (如何看待 Rust 的应用前景? – 知乎用户的回答)。可以发现,开发技术多元化,用最适合的技术开发最适合的应用是未来的趋势。而为这些不同的技术编写高性能的可控的公共组件,并轻松的和其他语言接口,正是 C语言的强项。所以不管应用层语言千变万化,对系统级开发语言C的需求还是那么的稳定,而这个过程中,哪里还有 C++的影子呢?
话题总结
所以说未来的趋势是:C x 各种语言混搭 的趋势,从TIOBE上 C++的指数十年间下跌了三倍可以看出,未来还会涌现出更多技术来代替各个角落残存的C++方案,C++的使用情况还会进一步下降。所以题主问学习纯C是否有前途,我觉得如果题主能够左手熟练的掌握 C语言,培养系统化的思维习惯和精确控制内存和硬件的技巧;右手继续学习各种新兴的开发技术,能够应对各个细分领域的快速开发,碰到新问题时能左右开弓,那么未来工作上肯定是能上一个大台阶的。至于C++ 嘛,有时间看看就行,逼不得已要维护别人代码的情况下写两行即可。
故事分享
古代用弓箭进行远距离攻击时,对射手要求较高,瞄准难度大,需要一直使劲保持准心。战斗中一个弓箭手开弓二十次就需要比较长的休息时间。弩的威力远胜于弓,秦弩的制造就如现代的自动步枪一般精密无二,它既可以延长射击,又可以精确瞄准。弩箭的发射速度更是弓箭的数倍,威力惊人。因为弩的操作非常简单,不需要射击技巧,平民很容易掌握它的使用方法。秦国靠着弩兵,在战争中取得了不少优势,被人称为 “虎狼之师”。
日本投降时,天皇下罪己诏。很多士兵不愿意相信这时真的,找种种理由拒绝相信。有的士兵甚至以为天皇的广播是敌人诱降的把戏,于是躲到丛林里继续三五成群的收集情报,袭击可以攻击的目标,等待上司来给他们下达新命令。直到好几年后看到周围的人都穿着日常的便装了,而来巡山的 “敌人” 也从士兵变为了巡逻队,他们都还觉得这是敌人的伪装。而同时,德国战败时,最后的党卫军一直战斗到 1957年才肯投降。
—————————————–
很多人觉得 java慢,C++快java 10倍以上已经是上世纪的事情了,现代的 java 只比 C/C++慢 70%,C++连1倍都快不了 java。也不要觉得动态语言慢,javascript只比C/C++慢 2.7倍。luajit只比 C++慢 5.8倍。在 jit技术发展的今天,C++在性能上离动态语言/java的差距越来越小,可易用性和生产效率上的差距,却和动态语言/java 比起来越来越大。
—————————
最后,补充一张图:
最后的图好赞
@dictator
哈哈,做了好长时间呀,这图片。
:-) 赞
游戏服务端:2008年后进一步进化为 C 和 脚本,完全看不到胖C++服务端了。
这个不准吧, 我看招聘中主要是c++和java,我之前只搞过c人家都是: 你没搞过c++???
所以现在还在找。。。。
最后的图不错。
Very good! I am studying the Java and Python techniques now.
大部分赞同,除了性能比较那部分。
我更看好go代替C++。
“战士不研究怎么上前线杀敌,天天在琢磨抢和炮的原理,成天在思考怎么用枪不会走火,用炮不会炸到自己,这战还怎么打?” 这句话太经典了。哈哈哈哈哈。
毫无营养的文章。。。
@LiLiLi
看了下楼主的博客,还是很佩服的,不过这篇文章说C++狗屁不行还是值得商榷的。
这样黑c++好吗?
“大数据:kafka, hadoop, storm, spark 都使用 Java”
— 虽然都是JVM系的,但Kafka和Spark是Scala写的,Storm是Clojure写的。
@shady
嗯,了解。
@august
有点娱乐精神嘛,再说我又不是去论坛的 C++ 板块发这样的文章拉仇恨,就在自己的博客上写写玩玩,何必认真呢?
呵呵
感觉像看了篇小说,因为我哪种语言都不精,所以并没有太大的感慨,但前一段时间写一个跨平台的小程序时,确实觉得C++有点,纠结。
一开始的笑话还是不错的,尤其是真正做过C++的人。对于喷子们(无论是不是C++的粉),很容易出现X点。
另外我只是觉得,无论C和C++,主要是可以让人了解一些偏底层的东西,尤其是一上来只写了java、c#这些更高级别的语言的亲。这其实也是C,C++都有的优点。
另外,C++确实被搞乱掉了。不过说句心里话,如果接触了比较不错框架的C++项目还是不错的,至少有些不错的框架代码非常简洁,写代码的很溜。
我是个写C++有点时间的,菜鸟一个。C++确实不是一个友好的语言,但是来学C++或者使用C++人也有一部分存在技能层次不齐。确实要写好C++,除了常规的要如何考虑如何设计一个业务抽象,或者框架。还要对C++一些乱七八糟的规则和“坑”有所了解。
用好C++感觉像怕珠穆朗玛,不是C++伟大,而是规范没做好。你对C++确实很了解,只不过我觉得你可能过激了一点,理性对待。不错的框架和代码还是有的,只不过少,语言分工和特性造成了。
luajit只比 C++慢 5.8 ?
所以是 10000000 跟 58000000 在線人數的差異囉?
c++ 用 100 台 server / luajit 要用 580 台?
果然是 “速度不輸” c++ 啊
现代的 java 只比 C/C++慢 70%,C++连1倍都快不了 java。
那为什么大型游戏不用Java来写。
@hank
你没有做过 server 吧,大部分 server,包括游戏和 WEB,是卡在I/O等待上,还有频繁的系统调用上。根本不是卡在逻辑的 CPU 计算上,即便有一些性能铭感的逻辑模块,用C写了导出给脚本即可,比如游戏的 AI,这样的模块并不多。
@Hell
服务端:早年 java 没有 NIO,现在有了,确实有很多大型游戏的服务端用 java 来写的。
客户端:java图形能力界面能力不强,客户端图形主要还是C++,我上文也说了。不过现在脚本和objc等也很多了。
C+动态语言确实感觉不错
@skywind
一直在寫 server …
但現在講的是 luajit 跟 c++ 的速度~ 不是指 I/O 等待的問題啊~~ 不是嗎? 難道 5.8 倍指的是 IO 等待的時間嗎?
而且試過 3000 玩家在同一個 “畫面” 上的 AStart 及 AOI 的壓力測試嗎? 不知道慢了 5.8 倍的 luajit 跑起來會如何….
用中文寫不出莎士比亞是中文的錯嗎?
用英文寫不出將進酒是英文的錯嗎?
c++ 真的不好嗎? 有時候用的人能力夠不夠很重要.
目前的工作有一部份是優化前人留下的代碼, 原本的寫法是直接在 IO 線程裡直接一把大鎖鎖住所有的用戶對象, 然後處理業務邏輯, 但要處理業務邏輯根本不需要鎖住所有的用戶對象, 有時只是某個用戶對象單獨的數據修改而已.
我接手協助優化是加入了智能指針,將大鎖切割為個別的小鎖, 整體效能有提升了不少, 也間接的解決不少 bug.
這個部份並不是要說 c++ 有多好用,只是要說好的語言也要有會用的人
如果思想錯誤, 一樣一把大鎖鎖住所有的用戶對象, 然後處理業務邏輯, 就算用 c/java/luajit/..其他的鬼東西 寫, 寫出來就會比較好嗎?
如果有神一樣的工具可以把豬一樣的設計師寫出來的鬼代碼變成天上掉下來的禮物,那我想也不需要所謂的資深程式設計師/主程, 直接叫美術人員寫程式就好了.
有些地方还是太片面了。
比如:
try-catch-throw 不止是c++有,很多其他语言也有。相比与函数返回错误,还是有一些进步的。
返回值的方式,需要调用函数的处添加错误判断代码,即便没有错误。而且,错误的传递依赖于调用处显式返回给下一个调用者。整个调用栈每一层都要作判断和传递。try-catch-throw能够让异常在调用栈上跳跃传递,只让真的能处理异常的地方去处理异常。
@hank
AStar不是一般放在客户端算好服务端验证的么?除非怪的AStar,服务端用C模块实现一下即可。关于你说的AOI,是有点计算量,但是Astar, AOI的代码量,在整个服务端里面少之又少吧。大部分还是在等待I/O。
@hank
C++要达到所谓“稳定会用”,起码要花费十年以上的时间,即便你达到了,你也不能保证你每个队友都达到,以及后续招聘的新人都达到,相反后端代码的话,java程序员只需要三年培训时间,就能写出差不多稳定的代码了。作为技术选型者,你敢选么?
@RisingV
我并没有说 try/catch 有问题,而是 “C++一方面承认作为系统级语言内存管理应该交给用户决定,一方面自己却又定义很多不受用户控制的内存操作行为”,属于 “语言逻辑出现矛盾”,其他 try / catch 的语言都是接管了内存的,不用担心半初始化问题,C++接管内存,却又没接管完的情况下,加入了 try / catch,就是一个 “逻辑矛盾”。虽然 throw的时候会自动析构,但很多时候是充满各种坑的,比如对待操作系统句柄这种同进程内不会自动析构的东西。
@skywind
一款前公司代理要改版的中國 MMORPG Server, 真的就是將 AStar 寫在 Server 裡, 改版時間不夠就真的只能在 Server 裡優化, 沒時間移植到 Client. 所以這真的不是 c++ 的錯, 就算用 java/luajit/… 寫, 還是有人會這樣寫.
@skywind
是不是真的要花費 10 年以上才能穩定會用, 我是不太清楚,雖然我寫程式的時間比不上前輩,但寫 c/c++ 的時間算算也超過 10 年了, 也不敢說自已用 c/c++ 就百分百穩定, 但要說 Java 程序員三年培訓時間就能寫出差不多穩定的代碼, 我只能說穩定不代表正確, 而且也不一定穩定. 主要還是程序員本身對要寫的項目本身是否了解.
就算前輩前面說的波音公司的笑話,真是用不好 c++ 的問題還是大學生根本不了解飛機程序該注意的細節, 就像我長期在寫遊戲程式, 如果換到去寫股票交易,也許第一天上線股市就大當機也不一定.
ios/object-c 應該算是穩定的語言了吧,應該比 java/luajit 穩定吧, 但前端同事寫遊戲, 將產品送交測試,程序是很穩定不會崩貴,但操作卻一直有問題, 替他檢查代碼, 發現將 select(fd+1, &fds, NULL, NULL, &timeout) <= 0 一律當作斷線處理… 然後數據讀取方式也有問題, 將代碼修改後就變穩定了, 問題也變少了, 但這要算是 ios/object-c 的問題嗎? 還是該同事是 ios 程序員但對 ios/object-c 其實不懂嗎? 我只能說是他對 TCP 程序該怎麼寫不了解, 因為問他為什麼那樣寫, 回答卻是….. 網路上 copy 來的…
也許前輩所在的公司在招聘新人時,有有經驗的人可以面試合格的程序人員, 但不是每家公司都有有經驗的人可以面試合適的程序人員, 說真的有時候也許可能連面試官本人經驗都不夠也不一定.
也許面試進來的人真的寫了 c++ 10 年, 不一定寫的出穩定能用的程序,但寫了 java 3 年也不一定寫的出穩定能用的程序啊, 一切還是在於程序員是否了解自已(要)寫的是什麼東西.
做為技術選型者, 會先以目標產品、通用技術及現有核心團隊可承載的技術為主, 再以招聘新人為次. 因為真的用了一個現有核心團隊無法承載技術的話, 如何去檢驗招聘的人是否合格? 如果出現問題誰來收尾?而不是以網路上誰說誰說或是那種程序員比較好招聘為主吧(當然如果沒有核心團隊又是另外一回事了).
幾年前在前公司時為了做 PC/android/ios 的真3D遊戲, 但當時的 unity3d 的人員(又要會程序又要會美術)不好招聘, 而且當時的 unity3d 也不好用, PC 端裝機量不足, 在手機上效能也不足.
團隊的開發人員也不足, 不太可能三個平台分開各寫一個 3D 引擎, 維護三套代碼, 最後的做法是用移植 irrlicht 在 PC/android/ios 用 c++ 開發, 不知道這樣的框架, 以當時的時空背景、環境包含資金, 不知道如果是前輩要如何選擇?
就该像java活着动态语言一样彻底接管内存
活着,应该是“或者”。
牛逼的一说,支持作者!感谢作者分享
文章比较长,没完全看完,就举点事实吧:
1:国外大公司google,facebook主流都是c++,其中f更是将php翻译为c++运行
2:国内大公司B,T主流都是C++
另外c++11以后的c++不知道用过多少
博主有点躁。
赞同32楼的,并不是你用不好就能说一个语言不好的!
@billowqiu
1. Google 正是用了很多 C++以后发现有各种问题,才发明 go 来逐步代替 C++
2. Facebook 主流是 php,把php翻译成C++或者上 HHVM不代表就是用C++来开发,就像你C++编译时先把C++翻译成汇编再送入汇编器,不代表你的代码是使用汇编来写的。
@YYFF
我最早用C++是94年,那时候你读高中了没?各种语言都只不过是描述事物的一种方式而已,就像物理学,不管相对论还是量子力学都只是描述自然的一种方式,连相对论都不敢说自己能够100%的诠释自然,C++何德何能敢称自己包打天下?C++就敢宣称自己没问题么?别一说C++的问题就说是使用者自己的问题,不要对 C++ 的问题采取回避和不愿意讨论的态度。
这种文章,对国人的软件技术,没有任何指导意义,仍然是远远落后于欧美。
不想证明C++有多好,因为我也不怎么用,就像说说文章的问题。
C++11以后list.size是O(1)。
cstring的strlen还是O(n)的呢,是不是证明C没有C++好?
另外,Gcc全部换成了c++编写。VS,Office,Chrome还有你说的Qt,也是C++写的。
Popularity上,今年比去年涨了超过60%,所以是在反弹咯?
70%的速度差是很大的。从没听说过有Java的大型游戏,游戏引擎都是C++和别的语言。而且很多benchmark的结果还是有好几倍的差距(比如Debian上的 10 tiny examples)。看图示你的图给的是编译好的java代码,跟你说的jit越来越快毫无关系。另外你的图都没有引用。
大型但是特别要求效率的部分用C++在正常不过了。
另外倚老卖老不是个平等讨论问题的态度。
其实除了C之外的其他语言,比如Java,python,ruby,RUST,SWIFT,OBJC暗地里也干了很多事情时不知道的。Java还要花额外时间去深入了解虚拟机呢,还有字节码,不然根本写不好高性能程序。
this article is very pertinent about C++.
can’t agree any more.
Hi, 像Handle這種東西,實際上在C++中是應該交給RAII來完成的。我也寫過不少語言,像Java的GC不代表file就一定close了,connection一定close了,是嘛。這個實際上也是資源泄露。GC有GC的好處,不過GC也不是萬能的。一個合格的Java程序員,也要能夠考慮到各個情況,將file給close掉。我們作爲程序員呢,要寫有良心的代碼。像前面 @hank 說到的 “問他為什麼那樣寫, 回答卻是… 網路上 copy 來的…”,有些時候,你看上去穩定的Java程序員,其實天天在在網絡上拷貝代碼。同時,看到這句話讓我還想起另外一句話 “你希望Code當中的錯誤被奇怪地Assert或者SegFault了,明確地以這種奇怪的方式告訴你,你的程序有問題呢,還是希望它慢慢地浸淫,直到有一天你看到的結果和你需要的大相徑庭。” 我引用這個不是說,SegFault是好的,或者是一個優雅的做法,卻是想說,我們寫代碼,實際上還是要對得起自己的良心才是。
我並沒有特別要保衛C++的意思,我很同意C++有很多問題。然而,我們是不是對C++太苛刻了。很多語言都有問題,並不是說,我們現在拿到的哪個語言就是沒有問題的,並且“好”語言的定義,也是一個非常不明確的東西。
很多人也都同意Javascript也有很多問題,可它還是Web Frontend中使用的最多的語言。TCP/IP在歷史上也不是最好的方案,Unix也不是。並且,就算是當下最“好”的東西,我們始終不敢保證,這也還是未來中,最好的東西。我只能輕聲勸解我的前輩們,或是在後輩們的耳旁細細說道,在期待更好的東西出來並有辦法替代現在的東西同事,我們還是良心地做好我們的事情,就是對這個世界盡了我們自己的力了吧。
MySQL核心纯C?博主你可曾看过一眼源代码?
其实我觉得吧,真是秀于林,风必吹之啊…..每次被引入到语言战争的风口浪尖的都是C++
@skywind
1:哪里有说明谷歌是要取代c++了;如果是这样的话其新开源的grpc,flatbuffer,pb3怎么不用go重写?
2:fb的web层是php这个没啥问题,虽然最后还是转换为c++而不是java;其后台服务难道不是c++,可以参看其开源的各种基础组件(osquery,fbthrift,mcroute。。。)
@Sai
“其实除了C之外的其他语言,比如Java,python,ruby,RUST,SWIFT,OBJC暗地里也干了很多事情时不知道的。Java还要花额外时间去深入了解虚拟机呢,还有字节码,不然根本写不好高性能程序。” 你没看懂我的意思,我没说语言不能在背后做事情,而是指出C++的逻辑矛盾:“承认自己作为系统级语言用户可以自由操作内存,另一方面自己又设定了很多不受用户控制的内存行为”,不像C,干脆没有任何背后操作,也不象java,python,要接管内存就彻底接管,不给用户操作。C++为了弥补这个逻辑矛盾做了太多补丁了。
@Adam
由于 C++ 并没有强制用户对各种资源采用RAII,并且封装了大部分 RAII,这样一个不严密的定义,导致这里极度容易失控。不出问题则以,一出问题就把人腿炸飞了。
@wing
别看那些周边代码,你看看 libmysys,libmysql,regex,myisam, sqlcommon, strings, vio 这些基础核心库是不是纯 C的?MySQL 的 C++代码也只是建立在这些核心库之上的一层应用逻辑而已。类似胶水语言的作用。你别看到两个 .cpp/.cc 文件就觉得人家是用 C++ 写出来的了。
@billowqiu
这是历史问题,新事物代替旧事物是有一个过程的,在这个过程中,旧事物并不会立马存在,它还会持续存在一段时期。Mozzila弄rust来代替C++自己也并不是一夜之间就能停掉所有C++项目,只是说不管 go 还是 rust 或者 java 他们的出现使得不管前端后端,原来很多必须用 C++ 的地方有了更好选择,他们会在未来逐步在各个领域替代 C++ ,使得 C++ 的应用范围在未来变得更窄,而能更好的无缝同 go/rust 整合的,就是C,不是 C++,就是这么一回事呀。
@Kimi
你如果觉得 Chrome是 C++ 开发的话,你可以打开:chrome://credits/# 看看,chrome用到多少底层库?这些底层库有多少是用纯 C开发的?至于 chrome本身,GUI呀,我已经说的很明白了 “C++适合开发 GUI”。
啥时候都成java了
腾讯 畅游 盛大 巨人
这里面4个公司 我待了3个 80%以上服务器是c++写
要是真的听你的改用java
只能去小公司了
完全不懂C++,但是聽說V8是C++寫的,沒錯的話請在請在清單裡留個位置。
“要不要出来黑一下C++呢?呵呵呵”,黑C++黑出了满满的优越感啊,说得好像你是王重阳刚从古坟爬出来一样啊。粗略扫了一遍,长篇大论的,确实擦到了一些黑边,可惜都是隔靴搔痒,你们这些C++黑老是黑不到点子上,让我很着急啊。另外这样长篇大论的,怎么也要弄几个成语、段子调和一下吧,如同嚼蜡一般,实在看不下去了。另外问一下,楼主这个排版还成啊,用什么软件写博呢?
其实java只慢705是不准确的,比如高频程序,一般现在都是亚微妙级(千万分之几秒)完成收到市场信号到发送出指令单。用java做,是达不到的,至少慢几百倍。
在google, facebook,性能敏感的系统还是大量用c++开发的,这几家界面倒基本不用c++。另外目前c++的主要战场是高性能计算,金融,图形学,给得都挺高的。
C最大的黑点就是出现了C++。 而且,Cpp一直以来保持自己首先是C,然后才++。也就是说,c有的优点,cpp全部具有!作者也就是那种手里有锤子,眼里都是钉子的货色而已。用cpp的时候,眼里只有oop,连其祖宗c都看不见。当发现cpp这把锤子敲不出洞来的时候,又企图用c这把锤子敲遍天下。 拿cpp跟Java比还有可比性,跟lua/Python就没有可比性。cpp应该是跟lua/Python共存的,就像c与他们友好相处一样。 至于他碰到那个800k的cpp项目,我想,原作者用c也会写出800k的代码来,问题照样是问题,不会因为换了语言就好转,只会因为换了人而得到改善。 另外,cpp的继承未必是为了oop,很多时候也是为了内存布局。什么隐式构造啥的,一个宏就搞定的,非要计较半天。c做值拷贝也一样的有这个问题。 而c++的模版,重载等功能的好处一点不提,难道是作者其实根本不懂这部分? 这个c++黑得没水平,原因无他,拿c来对比。
@RisingV
作者根本不知道c也有setjump函数,结果跟try-catch一样的效果
@tearshark
首先友情提示下,是 setjmp/longjmp,不是 setjump,别拼错。其次讨论问题就是论事,别摆谱说啥我觉得你不懂啥,你去看下什么书,要摆谱的话谁都会,2000年以前我就用过setjmp了,那时你开始学编程了没有?最后,C是有longjmp,但只是个辅助功能,不是语言级特性,这是有根本区别的,除了大量递归下降的编译器外,你见过几个开源 C项目在大规模使用 setjmp ?你又见过几个开源 C++项目不使用try-catch。
你94年出道,另外俩人什么时候出道没交代清楚,反正我看完那段的没感觉C + Python有多好,倒是觉得你比他俩强太多。这根本不是语言问题啊,我敢说肯定有人不服,坚信C++牛人比你做的更好,而且你只字未提这个项目中C++到底弱在哪,吵架往往就是这么开始的……