精华内容
下载资源
问答
  • 登录之CAS SSO入门精通(第一天

    万次阅读 多人点赞 2015-02-14 20:05:42
    2014年2015年工作太忙,对于一些经常跟我博客的读者们深深说声抱歉。同时,也在新的一年将之际,祝各位新春愉快,羊年洋洋洋。好了,废话少说,开始我们架构师之路的新的历程,SSO-单登录。什么是单登录?...

    啊。。。。。。it's quite a long time。


    好久没更新博客了,有一年之久了,一直在忙于公司的一些项目。2014年到2015年工作太忙,我也接触到了新的领域,认识了新的同事。


    对于一些经常跟我博客的读者们深深说一声抱歉。


    同时,也在新的一年将到之际,祝各位新春愉快,羊年洋洋洋。


    好了,废话少说,开始我们架构师之路的新的历程,SSO-单点登录。


    另外想以此SSO系列教程献给我那身体不太好的同事-小白同志,祝小白同志身体一直健康

                                                                                                                                                              ——叫你废话少说你还再啰嗦,你还说,好了,关掉,开始正经话题。

    什么是单点登录?什么是SSO?


    SSO就是单点登录!!!大笑


    SSO即Single Sign On。


    可是为什么我们要单点登录呢?为什么不能把所有的系统做成一个war包里呢?

    道理很简单啊,如果这个银行这个企业全是你一家公司里的一个项目组包下来了,然后是从头开始开发,你当然可以把所有的功能模块做到一个WAR工程中啊。


    可是很多时侯我们是做一个工程或者是两个工程然后需要和另一个工程去做结合,每个工程都有一个入口地址,对吧?那么我们从用户的角度出发来说:


    如果一个企业的工作人员需要操作4,5个不同的系统如:HR系统、报销系统、进销存系统还有企业内的eLearning系统和SAP系统,那么他要登录5次对不对?要登录5次?


    那么有人说了,为什么这么麻烦呢?我们不能把所有的系统除了一个主系统,然后让用户只要登录一次,再把其它系统的链接以菜单的形式挂在主系统的菜单点,然后去除登录功能,这样用户不就可以只需要登录一次了呢?


    答案当然是:你可以这样做。


    可是安全性呢?


    因此我们引入了单点登录的概念,我们可以想一下,用户面对10几个系统,这10几个系统只有一个“表皮”(主页),在这个主页中有许多的外挂连接,连向10几个子系统,这10几个子系统每个都需要根据用户名和密码来判断用户是否对于本系统有无操作权限?但是用户只需要在这个“表皮”上登录一次,当他点每一个菜单链接时,系统会自动把用户名和密码做一次匹配然后根据权限系统来判断该用户是否具有相应的权限,进而使得用户可以通过主页再链入不同的子系统中,这就是单点登录。


    或许是中文翻译的问题,我们就从Single Sign On这3个字来理解,只需登录一记,啊。。。这就对了,多个系统我只需要登录一次。


    我们进一步设想一下,其实用户还是登录了两次,为什么呢?


    对于正规的企业来说都有一个“域登录”,即WINDOWS域我们又称之为Active Directory,简称AD域,用户打开WIN7,WIN8, WINDOWS SERVER。。。bla...bla...bla...what every啦。


    此时他需要输入域帐号,登录一次。


    然后他进入WINDOWS桌面后,打开IE,点开公司内部OA系统,做报销或者是做请假,又登录一次。


    其实是两次登录。


    因此做的好的SSO,因该是怎么样啊?


    即让用户登录一次,就是用户一旦登录了公司的AD域后,他在IE里打开公司内部的一些网址都无需再做登录了,因为用户的AD域帐户就是它的系统帐户。


    如:公司内每个员工的邮箱帐号,它打开OUTLOOK后就自动连上了相关的MAIL服务器,然后该员工的AD域帐号加上@xxx.xxx这样的格式,这不就是他公司的邮件地址了,对吧?


    对不对?这就是一个SSO的活生生的例子。


    那么很多时候,确实,为了安全,我们可以让员工在登录了AD域后再打开IE,然后输入公司内的OA网址时再登录一次,这样做其实也是可以,而公司内的OA一般不仅仅只是一个系统,它一定一定是连接着多个子系统。


    比如说我们一个公司的OA系统是一个EAR,它下挂有10多个WAR。




    甚至一些公司还会外接如:SalesForce, SAP等其它系统,因此我们把员工打开的这层公司OA系统的最外面的这层“皮”,称之为PORTAL。


    对的,PORTAL里一定含有SSO,在此先提一下。

    下面是一些著名的调查公司显示的统计数据:

    • 用户每天平均16分钟花在身份验证任务上 - 资料来源:IDS
    • 频繁的IT用户平均有21个密码 - 资料来源:NTA Monitor Password Survey
    • 49%的人写下了其密码,而67%的人很少改变它们
    • 每79秒出现一起身份被窃事件 - 资料来源:National Small Business Travel Assoc
    • 全球欺骗损失每年约12B - 资料来源:Comm Fraud Control Assoc
    使用“单点登录”整合后,只需要登录一次就可以进入多个系统,而不需要重新登录,这不仅仅带来了更好的用户体验,更重要的是降低了安全的风险和管理的消耗。


    请看下面的统计数据:


    • 提高IT效率:对于每1000个受管用户,每用户可节省$70K
    • 帮助台呼叫减少至少1/3,对于10K员工的公司,每年可以节省每用户$75,或者合计$648K
    • 生产力提高:每个新员工可节省$1K,每个老员工可节省$350 - 资料来源:Giga
    • ROI回报:7.5到13个月 - 资料来源:Gartner   
    另外,使用“单点登录”还是SOA时代的需求之一。在面向服务的架构中,服务和服务之间,程序和程序之间的通讯大量存在,服务之间的安全认证是SOA应用的难点之一,应此建立“单点登录”的系统体系能够大大简化SOA的安全问题,提高服务之间的合作效率。


    以下是一个标准的企业内通过SSO来集成各个系统间的认证与权限的模型图


    好了,以上基本知识普及完毕开始我们的SSO实现。

    CAS SSO

    SSO实现有很多产品,我们今天选用的这个是耶鲁大学发明的CAS SSO服务器。这个CAS SSO是目前我看到过的功能较全的,使用也是最简单的配置式SSO服务器,它基于SPRING的原理,因此这个配置文件我们看起来因当是相当的熟悉的。


    它分为Server版和Client版2个模块,同时它对于一些其它功能特性如:数据库、LDAP协议(就是WINDOWS AD域使用的协议)、安全等还提供了一系列的插件。因此,在本例中,我使用的是:


    Server端:

    Cas Server 3.5.2


    Client端:

    Cas Client 3.2.1


    注:

    请严格按照我的版本号进行试验。


    什么叫Server端 ,什么叫Client端?

    看上图,假设我们有3个War包。

    • 一个叫cas-server.war,它放在tomcat里;
    • 一个叫cas-sample-site1.war,它放在jboss里;
    • 一个叫cas-sample-site2.war,它放在jboss里;

    那么位于tomcat里的cas-server.war,它就是我们的CAS的Server端,位于jboss里的两个war就是我们CAS的client端。

    SSO中的Server端与Client端概念搞清后,我们现在就开始布署吧。

    布署cas-server

    先说一下我们的环境:
     版本号 web端口
    tomcat69090
    jboss78080


    我们把Server端解压得到以下这样的一个文件夹


    它里面含了一堆的东西,关键在于以下这个文件夹


    进入该文件夹,找到这样一个war包。



    把这个war包解压后重命名成cas-server.war,放于tomcat的webapp目录中去,启动tomcat一切无误后即可。



    然后我们打开一个ie,输入http://localhost:9090/cas-server会得到以下这个界面,那就说明你的cas sso已经安装成功了。


    配置CAS SERVER

    添加依赖包

    在本例中我们将使用Oracle数据库中自建一个用户表来管理我们的用户名和密码,因此:

    1. 将oracle的ojdbc6.jar放入tomcat的lib目录内D:\tomcat\lib
    2. 将cas-server-3.5.2-release\cas-server-3.5.2\modules下的这几个文件拷入tomcat\webapp\cas-server\web-inf\lib目录内


    修改配置文件

    CAS SSO的好处在于它的配置文件是完全spring的,你只要懂spring就可以非常容易的在里面去添加修改自己的一些功能,我们在第一天的教程中为了尽量简单,我们只需要改动一个文件,它就是:

    tomcat\webapps\cas-server\WEB-INF目录下的

    deployerConfigContext.xml文件


    我们用纯文件编辑器打开它,找到下面这行:

    <bean  class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

    把它注释掉

    <!--
    <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
    -->
    然后再在它下面添加如下内容

    <!--
       <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
    -->
    
    
    <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
          <property name="dataSource" ref="dataSource" ></property>
          <property name="sql" value="select password from sys_user where user_id=?" ></property>
    </bean>

    好,这边我们看到了一个dataSource对吧,EASY,来。。。


    <!--
              <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
    -->
              <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
                <property name="dataSource" ref="dataSource" ></property>
                <property name="sql" value="select password from sys_user where user_id=?" ></property>
              </bean>
    	</list>
    </property>
    </bean>
    
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
        <property name="username" value="ymk" />
        <property name="password" value="password_1" />
    </bean>

    注意我加的这个dataSource的bean和刚才那段配置代码之间的位置对应关系哦,别胡乱搞一个回车就乱加一行哦。


    全加完了,怎么样啦?完成了吗?


    还没,CAS SSO严格意义上来说需要J2EE APP SERVER里实现HTTPSSSL的双向认证模式才能正常使用,但是我们因为这个是教程,因此不想搞了太麻烦,我们可以在“不使用HTTPS认证”的情况下也可以使用CAS SSO。


    为此,我们要关闭CAS SSO的HTTPS认证模式,编辑:


    tomcat\webapps\cas-server\WEB-INF\spring-configuration目录下的

    ticketGrantingTicketCookieGenerator.xml文件


    找到下面这行

    <bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
    	p:cookieSecure="true"
    	p:cookieMaxAge="-1"
    	p:cookieName="CASTGC"
    	p:cookiePath="/cas" />
    </beans>
    把这边的p:cookieSecure从true改为 false即可。


    然后我们在oracle中建一个用户表吧,建表语句如下:

    CREATE TABLE SYS_USER
    (
    	"USER_ID" VARCHAR2(16), 
    	"PASSWORD" VARCHAR2(8), 
    	 CONSTRAINT "PK_SYS_USER" PRIMARY KEY ("USER_ID")
    );

    该表中含有一条记录:


    这就是我们的用于测试的单点登录的用户名和密码了,很简单吧?


    全部保存后,重启tomcat,一切无误,然后我们打开一个ie,输入http://localhost:9090/cas-server会得到以下这个界面,那就说明你的cas sso已经安装成功了。


    我们在用户名中输入sso, 在密码一栏中输入aaaaaa,然后看到下面这个界面,即代表我们的cas server和我们的数据库已经完全连上了。


    如果我们不按照sys_user表中的用户名和密码就随意输入用户名和密码,那我们便会得到这样的结果:


    将不同的工程连接上cas server以实现单点登录


    按照这个图,我们将会有2个不同的war包

    • 一个叫cas-sample-site1.war,它放在jboss里;
    • 一个叫cas-sample-site2.war,它放在jboss里;
    我们在我们的eclipse里创建两个这样的war工程即可,这是非常简单的事,这2个工程都含有一个 index.jsp文件。


    cas-sample-site1

    在它的index.jsp文件中含有如下内容:

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>cas sample site1</title>
    </head>
    <body>
    <h1>cas sample site1</h1>
    
    <a href="http://localhost:8080/cas-sample-site2/index.jsp">cas-sample-site2</a>
    
    </br>
    <a href="http://localhost:9090/cas-server/logout">退出</a>
    </body>
    </html>

    cas-sample-site2

    在它的index.jsp文件中含有如下内容:

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>cas sample site2</title>
    </head>
    <body>
    <h1>cas sample site2</h1>
    <a href="http://localhost:8080/cas-sample-site1/index.jsp">cas-sample-site1</a>
    </br>
    <a href="http://localhost:9090/cas-server/logout">退出</a>
    </body>
    </html>

    这两个war工程都有一个lib目录,确保它们的lib目录里都有这样几个jar


    look, 注意要有cas-client-core-3.2.1.jar哦,它来自于:cas-client-3.2.1-release\cas-client-3.2.1\modulescas-client-3.2.1-release.zip解压出来的内容。


    这两个工程的web.xml可以说是完全一模一样,我们来看:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <display-name>cas-sample-site2</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>    
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
       <listener>
    		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
      </listener>
    	
      <filter>
    		<filter-name>CAS Single Sign Out Filter</filter-name>
    		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
      </filter>
      <filter-mapping>
    		<filter-name>CAS Single Sign Out Filter</filter-name>
    		<url-pattern>*</url-pattern>
      </filter-mapping>
    
      <filter>
    		<filter-name>CAS Validation Filter</filter-name>
    		<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
    		<init-param>
    			<param-name>casServerUrlPrefix</param-name>
    			<param-value>http://localhost:9090/cas-server</param-value>
    		</init-param>
    		<init-param>
    			<param-name>serverName</param-name>
    			<param-value>http://localhost:8080</param-value>
    		</init-param>
    		<init-param>
    			<param-name>useSession</param-name>
    			<param-value>true</param-value>
    		</init-param>
    		<init-param>
    			<param-name>redirectAfterValidation</param-name>
    			<param-value>true</param-value>
    		</init-param>
      </filter>
      <filter-mapping>
    		<filter-name>CAS Validation Filter</filter-name>
    		<url-pattern>*</url-pattern>
      </filter-mapping>
    
      <filter>
    		<filter-name>CAS Filter</filter-name>
    		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
    		<init-param>
    			<param-name>casServerLoginUrl</param-name>
    			<param-value>http://localhost:9090/cas-server/login</param-value>
    		</init-param>
    		<init-param>
    			<param-name>serverName</param-name>
    			<param-value>http://localhost:8080</param-value>
    		</init-param>
      </filter>
      <filter-mapping>
    		<filter-name>CAS Filter</filter-name>
    		<url-pattern>*</url-pattern>
      </filter-mapping>
    
      <filter>
    		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    		<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
      </filter>
      <filter-mapping>
    		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    		<url-pattern>*</url-pattern>
      </filter-mapping>
    </web-app>


    看到了没有,有这么一堆的listener和filter,而且它们一个不能漏,并且它们的顺序也是绝对不能够错的,一定要按照下面这个从上至下的顺序:

    1. org.jasig.cas.client.session.SingleSignOutHttpSessionListener
    2. org.jasig.cas.client.session.SingleSignOutFilter
    3. org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
    4. org.jasig.cas.client.authentication.AuthenticationFilter
    5. org.jasig.cas.client.util.HttpServletRequestWrapperFilter
    漏了一个,或者顺序错了,你将会发生下列情况:
    1. 可以正常登录,无法统一注销,即然是单点登录,那么我在任意一个站点上点“注销“是不是也因该是统一注销啊?
    2. 可以登录,可以统一注销,但是拿不到cas-server上登录的用户的user session,如果我们是两个系统,那么这两个系统是不是都有web sesssion?较常用的就是user session,那么如果你的顺序配错了,或者是你漏配了一个,你是得不到cas-server上传过来的用户的一些登录信息的,这个很糟糕,这将会为我们后面的编程开发带来烦恼
    3. 不能登录
    至于为什么会得到这样的一些结果?

    嘿嘿!

    我们在后面的课程中会来分析cas 单点登录的源码(这个过程一点不变态,很简单的,一说就通,跟着我的教程一步步走不难的),在深入源码中后你就可以看出为什么这几个东西它们有严格意义上的顺序的关系了。

    在这个web.xml文件里我们可以看到有两处出现了下面的这样的东西:

    <init-param>
    		<param-name>casServerUrlPrefix</param-name>
    		<param-value>http://localhost:9090/cas-server</param-value>
    </init-param>
    <init-param>
    		<param-name>serverName</param-name>
    		<param-value>http://localhost:8080</param-value>
    </init-param>


    记住,上面的那行代表我们的cas server的服务器所在的地址,当用户用上面的cas-server的登录界面登录成功后,cas server 会自动跳回用户在ie地址里输入的子系统地址的首页。

    如:我们先输入http://localhost:8080/cas-sample-site1,此时系统会先跳到http://localhost:9090/cas-server/login的画面要求用户先去做一次登录。


    那么cas server它是怎么知道子系统地址的首页位于哪个地址(哪台服务器上)的呢,那么你要”注册“这个地址给cas server。


    因此,第二行就是我们的具体的子系统的首页所在的地址。


    这样的地方在我们的web.xml文件中一共出现了两处:

    • 一处位于org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
    • 一处位于org.jasig.cas.client.authentication.AuthenticationFilter
    这2处如果没配好,你会遇到下列问题:
    • 登录后无法正常跳回子系统的首页
    • 无法正常退出
    • 无法做系统间切换时的跳转
    因此一定要注意啦!!!


    我们把两个工程通过ECLIPSE布署在JBOSS7上,然后运行起来吧。


    别忘了启动我们的Tomcat里的cas server哦。




    全部启动完毕后我们在IE浏览器里输入:http://localhost:8080/cas-sample-site1 


    此时浏览器显示如下画面




    我们在cas server的登录画面输入我们数据库表sys_user中的相应的用户名与密码后,再来看此时的浏览器它会跑到哪儿去?




    点击cas-sample-site2这个链接呢?




    然后点击“退出”这个链接




    此时我们再在浏览器里输入:http://localhost:8080/cas-sample-site2--有时浏览器有缓存,它还是会显示cas-sample-site2的首页,这时你可以点一下F5或者是刷新按钮(这个可以通过代码来避免jsp或者是html页中使用缓存来做到)



    look!

    由于是统一注销,因此一旦注销,两个WEB都无法访问了,必须要求“统一登录一下”,于是我们再次输入用户名和密码

    对不对。


    好了,第一天不讲太多,从明天开始我们会依次开始讲:


    1. 如何使用LDAP即模拟WINDOWS AD域的登录模式


    2. 如何在不同的web工程间获取“统一登录”时的用户信息即userprincipal


    3. 如何改造CAS SSO自带的登录界面


    4. 如何使得我们的CAS SSO可以支持类似于淘宝这种“多租户”的概念


    差不多所有内容预计在5-6课左右,敬请期待。 




    展开全文
  • &gt;&gt;&gt; import datetime &gt;... (datetime.datetime(2010,03,01) - datetime....# 当天所在当月的号 datetime.datetime.now().day # 当前月份 datetime.datetime.now().mouth # ...

    >>> import datetime

    >>> (datetime.datetime(2010,03,01- datetime.datetime(2010,02,01)).days

    28

    # 当天所在当月的几号

    datetime.datetime.now().day

    # 当前月份

    datetime.datetime.now().mouth

    # 当前年份

    datetime.datetime.now().year

     

    print ((datetime.datetime.now()-datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M"))

    print ((datetime.datetime.now()-datetime.timedelta(minutes=1)).strftime("%Y-%m-%d %H:%M"))

    print ((datetime.datetime.now()-datetime.timedelta(seconds=1)).strftime("%Y-%m-%d %H:%M"))

     

    now = datetime.datetime.now()

    # 3天前

    three_days_ago = now + datetime.timedelta(-3)

    # 3天前的前12分钟0秒

    three_days_ago = now + datetime.timedelta(-3,-12,0)

    这个datetime模块中往前往后推算时间都行

    展开全文
  • C++Java,10年技术生涯的几点思考

    万次阅读 热门讨论 2011-04-18 09:51:00
    不知不觉,做程序工作已经10年了,最初学习C++Java,困惑清晰,感觉真的有不少东西可写,不过总觉得不成体系,大概看了太多八股文章的缘故,被憋得实在难受。所以不管了,想到什么写什么吧。1、C++Java C++...

       不知不觉,做程序工作已经10年了,从最初学习C++Java,从困惑到清晰,感觉真的有不少东西可写,不过总觉得不成体系,大概看了太多八股文章的缘故,被憋得实在难受。所以不管了,想到什么写什么吧。

    1、从C++Java

        C++Java谁快?从算法上讲我认为毫无疑问是汇编〉C++Java,不要迷信某些个别评测,单纯的回圈测试什么的,比如JNode的官方网站上有Java写的JVM的性能和SUNJVM

    进行性能比较的结果,JNode中用Java写的JVM竟然能比SUN公司用C++写的JVM还快!编译器完全可以作针对性优化影响测试结果,毫无意义的东西。而且,评测结果不会具备多少实际意义,真正的应用系统的效率是80%取决于整体的设计架构,而非你使用哪种语言。所以讨论汇编、C++Java谁更快这个问题的人恐怕更多是为了自己的面子考虑,虽然Java当前如日中天,但其总是针对C++的批判性态度却再明显不过,所以Bruce才会有“C++不垃圾,只是Java很傲慢”之说。

        C++Java根本的区别是什么?我认为毫无疑问是内存分配。编程思想和设计模式是活的东西,和语言没有直接关系。Java没有指针,C++写程序也可以只用引用。JVMJava在内存管理上真正有别于C++的地方。JVM的好处是显而易见的,跨平台、更智能的内存管理,但能解决所有问题吗,答案是否定的。

        Java没有内存泄露吗?当然不是,我认为java的内存泄露往往比C++更加难以排查,因为JVM的缘故,程序员没法直接对内存进行操控,隐患往往藏的更深。我曾经花了大量时间研究JVM的内存机制,虽然也有了不少心得,但直到现在仍然处于迷惑期。循环引用,缓存机制不合理,Spring等常态Bean的属性重复加载都是可能吃内存的元凶。

        对于一个单一的,低用户低并发的系统,使用Java是很舒服的,程序员不用去考虑太多事情,照着业务逻辑做设计编代码就行,不用管内存分配,不用管并发和互斥(其实还是要管的),就算万一有内存泄露的隐患,大不了每天重启JVM一下就能解决了。但对于一个可能在多个应用环境中部署的软件产品而言,内存泄露这种问题却绝不能放过。我曾经遇到过在一个环境中运行非常良好,但在另一个环境中却天天出问题的情况,即使每天重启JVM也无济于事。当时怀疑过很多方面,网络、数据库、容器等等。那时还不是很有概念,现在想起来还是后来好好看程序,优化了不少代码,解决了几个内存泄露,这样才最终解决了不稳定的问题。举例来讲,在应用环境A中,服务器性能较好,JVM2G内存,某个应用存在内存泄露的隐患,每次大约造成2M的内存消耗,这样1000次左右就没有内存可用了,就会造成JVM性能大幅降低。但在应用环境B中,服务器就没那么好的性能了,JVM仅有256M,那么100多次操作就足以导致问题出现。而且,每个应用环境的应用使用率是不一样的,在A中如果每天仅出现10次隐患应用操作,2-3个月都不会暴露问题,而且即使使用内存分析工具,开始阶段也很难查出有无问题,但在B中,如果每天有100次隐患应用操作,只需一天问题就出现了。但实际应用过程中,应用的使用率往往很难精确统计的到,也无法预判,这也是造成问题排查困难的关键因素之一。应用环境的不确定性不单体现在地域上,也体现在时间上,不同时间的相同应用环境也不尽相同。挑选一个应用环境,常态性监测JVM的内存情况是避免这类问题发生的好办法。

        结论就是,对于中高端的产品化,多用户,高并发应用,JavaC++一样,不考虑内存是不可能的,毕竟语言最终操纵的还是计算机。

        Java的优势在哪里?我认为其在中低端应用上的门槛更低。对大多数小型信息管理类系统而言,并不需要很严谨并且考虑周到的设计和编码,学习java可以让一个新手很快上路,而C++却没有这种优势,动不动就越界是新手常犯的错误。在一个通常的软件团队里面,水平一定会有高低,而且也不是每个人都能通过学习进入深层次,这是C++难以解决的问题,Java在由于规范性方面的优势更加适合新手使用。

        C++就像手动档汽车,Java更像自动档,尽管越来越多人愿意开自动档,可是要想真正跑得快,赛车还得手动挡的。

        问题出现总会让人头疼,追根溯源常常也会非常艰苦和漫长,但只要还有办法,就不能放弃,规避问题可以解决阵痛,但永远无法治根。

     

    2、关于云计算想到的

       毫无疑问云计算的概念被扩大化了,云服务、云存贮,SAASIAASPAAS,理论和概念早已满天飞。但当我仔细读来,却发现大多还是新瓶装旧酒。虽然说还是有不少实质性内容,但与真正的分布式计算概念还是想去甚远。在网络越来越发达的时代背景下,存贮、软件、外设甚至内存都网络化了,唯一缺少的就是CPU,依靠网络使大量CPU协同工作真的是个很诱人的想法,但也是困难而遥远的事情。也有人认为Cloud Computing是个过度炒作的东西,我觉得有一定道理,如果要我选择,我也会希望把自己的东西放到自己的电脑上,我会更希望在任何地方使用便携设备随时操纵我的电脑,却绝对不是放到一个看不见摸不到的“云端”上头,天天被“云端”盘剥和控制。因此,如果云端仅仅是服务或存贮的集中式管理,它是不值得如此进行炒作的。

       其实我觉得我不是一个重组概念进行炒作的反对者,炒作对于技术和社会进步是有一定作用的,但水可载舟、亦可覆舟,将一些本无关系的东西牵强附会的联系在一起进行炒作,只会搅乱理论和学术体系,而理论体系的混乱一定会导致交流上的障碍-----虽然交流变得更多(必然变得更多)更方便了,可是交流的障碍却大幅度增加了,同样的一个名词可以被一百个人给出一百个解释,本来一句话可以说清楚的事情,现在变成了几十句才能说明白。

       药厂可以把10几块钱的药重新包装卖200-300块,利润当然是惊人的,可是赚到了钱的老板们却天天打算着转移资产到国外,认为国内没有可持续的发展。这样的人到底是高素质还是低素质呢?

             我上大学的时候曾经在医院实习,见过一个食物中毒的病人家属连夜赶了几十里山路,把一堆借来的硬币交给医院做透析;后来工作了,搞图书馆的项目也知道很多地方的人连100块钱的借书证押金都捉襟见肘。那些天天生活在优越环境下的概念重组专家们会为这些人群考虑多少呢?“云端”的概念炒作显现了他们的垄断思想,现在中国的贫富差距基本还是在财产方面,信息方面基本还是对等的,这也是一个农村的孩子经过十几年苦干可以成为大企业家的前提所在。可是“云端”一来,你的一举一动都在我掌控和监视之下,没错,你是方便了,也少花钱了,可是却失去了信息方面的平等地位,于是,屁民将永远是屁民,永远没有咸鱼翻身的机会。

     

    3、关于信息爆炸

             10年来我也做了很多技术方面的工作了,最初几年看到一项新技术、新概念,肾上腺激素浓度就会大幅度增加,要是不用一下晚上恐怕觉都睡不着。可是后来慢慢地就变得理性多了,技术的选择一定要根据需求来,绝不能为用技术而用技术。很多的新技术、新概念,看几眼就差不多知道来源,也知道优点和缺点了。以前总以为环境得适应程序,后来明白了程序得适应环境。

             大型的应用系统,越简单越好,如果做不到简单,宁可拆分为多个系统单独设计。否则,当我面对一大堆连自己都难以看懂的概念和代码,真会有抓狂的感觉。

    CSDN是不错的技术社区了,但是依然缺乏体系组织和管理。论坛、知识库,Q&A,这些东西的模式差不多,虽然方便了信息交流,但缺乏信息的组织和管理。比如我希望做一个信息系统,那应该选择什么样的技术?这个问题目前只能靠自己去摸索,慢慢体会,找到真正适合自己的技术方案。Wiki可能是更好的平台,但普及度不够。

    其实每一个Questioner或者Answerer都在极力寻求相互之间的共同语言,共同语言和语义的理论体系形成之后,交流才能顺畅。翻翻CSDN的帖子,不乏问东答西的案例。一个交流平台如果能形成一套语言和思维方式,那就是非常成功的了。而这也使得技术选型的模型成为可能,当你想采用一套新技术时,Google一下,各说各话,对的有,错的也有,搜索引擎为何判断不出已定论的东西谁对谁错呢,就是源于语义的复杂性。信息的膨胀速度远没有我们想象中那样快,其中相当一部分是语言语义产生的泡沫,挤掉这些泡沫呢?信息真的有统计数据显示的那么“海量”吗?

    统计数据经常是面子工程强有力的支撑者,可扔掉这些浮华,细细究一下统计数据是怎么做出来的?常常就会让人哭笑不得,而且大多是7分真,3分假,或偷换概念,总之目的就是把一棵小草说成一座森林。信息是有欺骗性的,商业运作会大量运用这种特性,换来的除了肾上腺素之外还有人和人之间不信任的感觉。

    信息爆炸的时代,交流的作用变成空前重要,但在交流越来越方便的同时,效率也越来越低了。也许几十年后,人类会不堪信息的重负,那时信息规范化和有序化才会真正站上历史的舞台。

     

    展开全文
  • 透漏几点面试的真相

    千次阅读 多人点赞 2019-03-06 00:20:50
    最近不少人都在找工作,很多人开始抱怨,工作难找,不少人后台问我怎么办,讲真,我也无能为力,年前我就说了,今年节后工作竞争一定比较激烈的,不过,既然这么多人问起,我想了想,还是说几点面试的大实话给你们吧...

    最近不少人都在找工作,很多人开始抱怨,工作难找,不少人后台问我怎么办,讲真,我也无能为力,年前我就说了,今年节后工作竞争一定比较激烈的,不过,既然这么多人问起,我想了想,还是说几点面试的大实话给你们吧。

    我以前在公司打工的时候,大大小小说面试过几百人是有的,然后业内不少猎头、HR 以及各种主管打交道的也不少,所以多少对面试比大部分人要了解更清晰点,以下几点肺腑之言告知下大家:

    很多面试官在拿到简历后,让应聘者先来个自我介绍,除了看下应聘者的表达能力之外,很大的一个原因是,面试官可能没来及看你的简历,然后在你自我介绍的时候顺便就看下简历了,所以这个环节其实没想象的那么重要,用简练的语言介绍清楚自己的履历就好了。

    很多应聘者面试没通过,总把原因归咎在自己的简历模板上,怪自己简历模板逼格不够高,然后想尽各种办法去找一些模板,甚至于付费买所谓高大上模板,但其实简历模板只是锦上添花而已。

    你得清楚,面试官啥样的简历没见过?除非你是应聘设计师,简历模板可以体现出自己的设计水平,大部分职位,简直模板只需要简洁就好,重要的是简历上的内容,简历里的履历与项目经验,能体现出你的个人能力,这才是面试官最看重的。

    所以你的简历被拒了,不要老把原因归咎在自己的简历模板上,应该把重心关注在简历上如何能体现自己的专业能力上。

    面试的时候,你可能会被问这么一个问题,你有什么缺点?

    很多应聘者比较耿直,就说了自己各种一大堆缺点,什么自制力不行,喜欢打游戏,打游戏一打就是一天,什么脾气很大,经常跟别人闹矛盾等等之类的,别笑,这样回答的一大堆。

    有人可能会说,这不是体现很耿直么?耿直是好事,但是我认定你很耿直,那我就认定你说的是真实的,你喜欢打游戏,一有时间就打游戏,自制力还不行,虽说业余时间都是自己的,但是没有任何一个企业老板希望自己的员工一下班就打游戏,这对自己的个人能力成长也好,对企业也好,都不利,这种耿直,你说有用么?任谁看到这样的缺点,也一定不会录用啊。

    所以,这个问题,缺点你随便说点无关紧要的,但是尽量不要说影响工作的缺点,至于能说什么,你们自行考虑下,我在这里说个范本,很可能造成最后一堆人面试都这样说,那反而变成面试套路了。

    很多人会觉得自己学历一般,不是 985、211,抱怨一些企业只要名校的,讲真,这没啥抱怨的,人家前半生努力了,自然得有点优势。对于企业来说,其实收到的简历一大堆,这样也算是减少筛选成本了,如果你学历一般,你该咋样?你要想办法体现出自己的能力。

    有一点你们得须知,没有任何一个企业愿意错过人才的,同样,学历一般的牛人其实挺多的,重要的是,你要在简历上体现自己的能力。比如 GitHub 上有个开源项目很流弊,更成百上千人 follow、star,比如经常写博客,博客有点影响力等等,比如自己业余时间做了个作品,小有名气,用户量还可以等等,这些都该在简历上重点突出来,这些都是会给你加分的。

    说个我遇到的搞笑的,我记得有段时间,技术圈都流行简历上附上自己的 GitHub 账号,这个自然没错,不过我见到不少简历上附带的 GitHub 账号是空白的,也没项目,也没提交任何代码,就是个空白,我真是醉了,附带 GitHub 账号,不是说让你注册个账号就带上,你账号上起码有项目吧,啥都没有,你附个空白的账号有什么意义呢?

    不要投递同一个公司的多个职位。很多人其实经验比较丰富,比如有前后端通吃的,投递简历的时候,两个岗位都投递,自己想的是,两个岗位我都能做,需要我做哪个我就去做哪个,这样面试通过的概率挺大。想的倒挺好,但是企业可不会这样想,企业只会想你这个人其实给自己定位不清晰,自己都没想好,几乎遇到这样的大概率是拒绝。

    有多个领域的技能与经验是优势,但是投递同一家公司的时候必须得自己定位清晰,然后其他技能作为自己的一个优势,面试的时候反而会给自己加分,这两种做法,最后造成的面试结果差距非常大,切忌自己定位要清晰。

    很多人投递简历的时候,是海投,这个可以理解,毕竟广撒网可以增加面试机会嘛,但是有的都约去面试了,你对你要面试的这家公司具体做什么的,什么领域,什么产品一问三不知,未免也太说不过去了吧,去面试之前,能不能稍微花点时间,了解下这家公司是做什么的?核心产品是什么?用心点的,可以了解下这家公司的商业模式,技术团队,业务细节等等,这都是给自己增加面试通过率的细节。

    面试的后半段,一般都会问,你有什么想要问面试官的么?

    有的人看到这个问题,就会问,有补贴没?五险一金按什么比例缴?福利待遇咋样的?真的,这些问题不是说不重要,而是这些细节问题,一般都是会最后确定录用你的时候,由人事部门给你详谈的,面试官问你这个问题的时候,你该问下,公司的技术团队规模,氛围,业务发展,你这个岗位要做的事情,未来公司的发展方向等等,这些才是你该关注的,你别不信,如果面试官问到这个问题,你上来问一句,公司五险一金咋交的等等,前面也许谈的不错,但是这个问题直接就暴露了你太过于关心细枝末节了,格局不够,这些小细节问题,后面会有专人跟你聊的。

    反正,我见过很多前面聊的蛮愉快的,但是后面这个问题聊崩了的。

    以上,就是一时间想到的面试过程中几点需要特别关注的,另外提醒一句,如果你不想立即换工作,就想更新下简历,或者就想投递下看下市场机会,务必注意,一些招聘网站更新简历,一般自己公司 HR 都会收到通知的,而且几乎每个公司都是这样的,这点务必注意下,怕的是,你本来就是随意更新下简历,然后被公司知道你有离职的打算,最后造成蛮尴尬的局面,这里简单提醒下。

    总之,面试首先最重要的还是个人实力,但是在个人实力没问题的基础上,就是要体现自己的综合素质,以上几个点,恰恰是反应自己综合素质的几点,希望这篇文章对大家的面试有点帮助。

    PS:本文原创发布于微信公众号「stormzhang」,回复关键字「程序员」获取一份 15 本程序员经典电子书。

    展开全文
  • 在实际的项目中,我们常常有这样的需求,计算某个时间点加上某个时间段后(几天几小时几分钟)的时间。如: 2016-04-05 09:29:15 要加上2天4小时5分钟后的时间: 即:2016-04-07 13:34:15。function getEndTime...
  • 关于裁员几点看法及建议

    千次阅读 多人点赞 2019-11-26 07:20:00
    最近网易裁员事件引起广泛关注,昨天网易针对此事,也发了声明,到底谁对谁错,孰是孰非?我们作为吃瓜观众实在是知之甚少,所以不敢妄下定论。身处软件开发这个行业,近两年来,对...
  • 年,Python 的受欢迎程度可谓是扶摇直上,加入 Python 学习大营的人越来越多。不过,随之而来的是,竞争越来越激烈。迷茫的声音也越来越多,我经常看到粉丝在后台...
  • java获取当前时间到凌晨0的秒差

    千次阅读 2019-11-02 14:38:59
    几天个每日分享给予奖励的个需求,用户每天可以分享多次,考虑的不需要入库,将用户的分享次数用redis记录,每天凌晨0删除key 翻阅了好篇文章,看到个坑,分享一下 public Long ...
  • 大本营:lan6193.blog.csdn.net ...获取两个时间点时间差 获取当前时间及其秒、毫秒、纳秒数 now := time.Now() //获取当前时间 ==>2019-08-21 11:30:51.2470317 +0800 CST m=+0.004501101 fmt.Print...
  • 用C语言解“然后是几点”问题

    千次阅读 2020-01-15 19:06:50
    读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • C语言之计算某天为年中第几天

    万次阅读 2017-05-21 11:58:11
    输入某年某月某日,判断这一天是这一年的第天?程序分析:以5月21日为例,应该先把前5个月的加起来,然后再加上21天即本年的第天;这里还有一个特殊情况,那就是2月份的天数和闰年平年有关,如果是闰年且输入...
  • 7-16 然后是几点(15 分)

    千次阅读 2018-02-25 08:37:24
    7-16 然后是几点(15 分)有时候人们用四位数字表示时间,比如1106表示11点零6分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。读入两个数字,第个数字以这样的四位数字表示当前时间,第二个...
  • 7-6 然后是几点(15 分)

    千次阅读 2017-12-27 21:08:50
    读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • 7-2 然后是几点 (15 分)

    千次阅读 热门讨论 2019-05-28 19:50:09
    读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • 但简单来说,每件事都有它的两面性,重装系统也不亚于,好和坏都需要我们自己了解清楚具体情况再做判断,那么,电脑多久需要重装次系统?下面快启动小编为大家分享下详细的操作,从而减少更多的小麻烦小问题哦。 ...
  • PAT练习基础编程题目之 然后是几点

    千次阅读 2016-01-09 13:20:44
    读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • 、在我们的日常开发中,要用到统计某个时间段的数据,而特定的时间点需要...strtotime()是个功能比较强大的函数,可以很方便的获取我们想要的时间戳,然后通过配合date()函数获取我们所需要的时间点! ...
  • 读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • PAT-然后是几点(简单编程题)

    万次阅读 2015-12-24 09:45:00
    读入两个数字,第个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,即5点30分表示为530。注意,第二个...
  • java 获取几天前和天后的时间

    万次阅读 2017-03-27 11:04:37
    * 得到几天前的时间 * @param d * @param day * @return */ public static Date getDateBefore(Date d,int day){ Calendar now =Calendar.getInstance(); now.setTime(d); now.set(C
  • 例如,你可能需要生成一份前一天数据更新的日报告,你可以分别比较表的每一行或找到行的交集和并集。 ⊙ Checking the state of transactional data at a particular time.For example,you could verify the ...
  • springboot中关于context-path的几点说明

    万次阅读 2018-10-18 22:16:25
    今天和项目组的前辈做个springboot项目,但是在项目中${pageContext.request.contextPath}突然获取不,导致&lt;%@include file="/include.jsp" %&gt;不能使用,同时写各种绝对路径也获取不...
  • 推荐在NUS读博师姐的篇文章:NUS博士毕业后的几点感受:学术与人生 偶尔看到自己的几年前写过的申请PhD面试经历的文章,不知不觉就过了七年,那篇文章也使我认识了很多来新加坡或者申请出国的朋友 现在,我...
  • AIX下取前一天时间

    万次阅读 2015-10-19 15:32:03
    AIX的默认dtae命令是不支持-d参数的,导致大家写脚本很痛苦,没法简单取得前一天时间。 下面有简单方式可以取得: YESTERDAY=`TZ=aaa24 date +%Y%m%d` echo $YESTERDAY 或者是 #!/bin/sh T
  • public static String addDateMinut(String day, int x)//返回的是字符串型的时间,输入的 //是String day, int x  {  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")...
  • 本站文章均为 李华明Himi 原创,转载务必在明显处注明:(作者新浪微博: @李华明Himi ) 转载自【黑米GameDev街区】 原文链接: ... 今天起,Himi将陆续的会持续更新一些Coco
  • 思路:定义个数组,包含一到十二月各月的天数,由键盘输入年、月、日,将之前月份的天数累加,再加上当前的天数就是总天数。如果该年是闰年,总天数要加一。 程序代码: #include <stdio.h> int fun(int ...
  • 通过个时间戳计算当天0点时间

    千次阅读 2015-11-05 18:49:30
    比如某7的活动,一般开始和结束时间都是需要活动当天的零点时间。 公式为:NowTime - (NowTime + 8 * 3600) % 86400 思路为:现在时间 - 今天的秒数。 因为NowTime % 86400是0时区当天的...
  • 火车票订票系统的几点优化思考

    万次阅读 热门讨论 2012-01-09 11:06:19
    、场景分析 1、平时访问量不高,但是春运几天会出现瞬间高峰 ...使用RAC来做数据库集群将订单按照天来做日期类型的表分区存储数据做主库,将非关键性数据查询放到从库上提取计算规则比较复杂的逻辑放t

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 876,635
精华内容 350,654
关键字:

一天的时间从几点到几点