精华内容
下载资源
问答
  • 面试官:你连SSO都不懂,就别来面试了

    万次阅读 多人点赞 2020-04-02 13:33:56
    和www.java4y.com,一个SSOwww.sso.com 首先,用户想要访问系统Awww.java3y.com受限的资源(比如说购物车功能,购物车功能需要登录后才能访问),系统Awww.java3y.com发现用户并没有登录,于是重定向到sso认证中心,并...

    前言

    只有光头才能变强。

    文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

    有几个网站就一直躺在我的收藏夹里边:

    收藏的一些网站

    于是我决定来整理一波

    一、什么是单点登录?

    单点登录的英文名叫做:Single Sign On(简称SSO)。

    初学/以前的时候,一般我们就单系统,所有的功能都在同一个系统上。

    所有的功能都在同一个系统上

    后来,我们为了合理利用资源和降低耦合性,于是把单系统拆分成多个子系统。

    拆分成多个子系统

    比如阿里系的淘宝和天猫,很明显地我们可以知道这是两个系统,但是你在使用的时候,登录了天猫,淘宝也会自动登录。

    登录了天猫,淘宝也登录了

    简单来说,单点登录就是在多个系统中,用户只需一次登录,各个系统即可感知该用户已经登录。

    二、回顾单系统登录

    在我初学JavaWeb的时候,登录和注册是我做得最多的一个功能了(初学Servlet的时候做过、学SpringMVC的时候做过、跟着做项目的时候做过…),反正我也数不清我做了多少次登录和注册的功能了…这里简单讲述一下我们初学时是怎么做登录功能的。

    众所周知,HTTP是无状态的协议,这意味着服务器无法确认用户的信息。于是乎,W3C就提出了:给每一个用户都发一个通行证,无论谁访问的时候都需要携带通行证,这样服务器就可以从通行证上确认用户的信息。通行证就是Cookie

    如果说Cookie是检查用户身上的”通行证“来确认用户的身份,那么Session就是通过检查服务器上的”客户明细表“来确认用户的身份的。Session相当于在服务器中建立了一份“客户明细表”

    HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一个用户。于是乎:服务器向用户浏览器发送了一个名为JESSIONID的Cookie,它的值是Session的id值。其实Session是依据Cookie来识别是否是同一个用户

    所以,一般我们单系统实现登录会这样做:

    • 登录:将用户信息保存在Session对象中
      • 如果在Session对象中能查到,说明已经登录
      • 如果在Session对象中查不到,说明没登录(或者已经退出了登录)
    • 注销(退出登录):从Session中删除用户的信息
    • 记住我(关闭掉浏览器后,重新打开浏览器还能保持登录状态):配合Cookie来用

    我之前Demo的代码,可以参考一下:

     /**
     * 用户登陆
     */
    @PostMapping(value = "/user/session", produces = {"application/json;charset=UTF-8"})
    public Result login(String mobileNo, String password, String inputCaptcha, HttpSession session, HttpServletResponse response) {
    
        //判断验证码是否正确
        if (WebUtils.validateCaptcha(inputCaptcha, "captcha", session)) {
    
            //判断有没有该用户
            User user = userService.userLogin(mobileNo, password);
            if (user != null) {
                /*设置自动登陆,一个星期.  将token保存在数据库中*/
                String loginToken = WebUtils.md5(new Date().toString() + session.getId());
                user.setLoginToken(loginToken);
                User user1 = userService.userUpload(user);
    
                session.setAttribute("user", user1);
    
                CookieUtil.addCookie(response,"loginToken",loginToken,604800);
    
                return ResultUtil.success(user1);
    
            } else {
                return ResultUtil.error(ResultEnum.LOGIN_ERROR);
            }
        } else {
            return ResultUtil.error(ResultEnum.CAPTCHA_ERROR);
        }
    
    }
    
    /**
     * 用户退出
     */
    @DeleteMapping(value = "/session", produces = {"application/json;charset=UTF-8"})
    public Result logout(HttpSession session,HttpServletRequest request,HttpServletResponse response ) {
    
        //删除session和cookie
        session.removeAttribute("user");
    
        CookieUtil.clearCookie(request, response, "loginToken");
    
        return ResultUtil.success();
    }
    /**
    * @author ozc
    * @version 1.0
    * <p>
    * 拦截器;实现自动登陆功能
    */
    public class UserInterceptor implements HandlerInterceptor {
    
    
    @Autowired
    private UserService userService;
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        User sessionUser = (User) request.getSession().getAttribute("user");
    
        // 已经登陆了,放行
        if (sessionUser != null) {
            return true;
        } else {
            //得到带过来cookie是否存在
            String loginToken = CookieUtil.findCookieByName(request, "loginToken");
            if (StringUtils.isNotBlank(loginToken)) {
                //到数据库查询有没有该Cookie
                User user = userService.findUserByLoginToken(loginToken);
                if (user != null) {
                    request.getSession().setAttribute("user", user);
                    return true;
                } else {
                    //没有该Cookie与之对应的用户(Cookie不匹配)
                    CookieUtil.clearCookie(request, response, "loginToken");
                    return false;
                }
            } else {
    
                //没有cookie、也没有登陆。是index请求获取用户信息,可以放行
                if (request.getRequestURI().contains("session")) {
                    return true;
                }
    
                //没有cookie凭证
                response.sendRedirect("/login.html");
                return false;
            }
        }
    }
    }
    

    总结一下上面代码的思路:

    • 用户登录时,验证用户的账户和密码
    • 生成一个Token保存在数据库中,将Token写到Cookie中
    • 将用户数据保存在Session中
    • 请求时都会带上Cookie,检查有没有登录,如果已经登录则放行

    如果没看懂的同学,建议回顾Session和Cookie和HTTP:

    三、多系统登录的问题与解决

    3.1 Session不共享问题

    单系统登录功能主要是用Session保存用户信息来实现的,但我们清楚的是:多系统即可能有多个Tomcat,而Session是依赖当前系统的Tomcat,所以系统A的Session和系统B的Session是不共享的。

    系统A的Session和系统B的Session是不共享的

    解决系统之间Session不共享问题有一下几种方案:

    • Tomcat集群Session全局复制(集群内每个tomcat的session完全同步)【会影响集群的性能呢,不建议】
    • 根据请求的IP进行Hash映射到对应的机器上(这就相当于请求的IP一直会访问同一个服务器)【如果服务器宕机了,会丢失了一大部分Session的数据,不建议】
    • 把Session数据放在Redis中(使用Redis模拟Session)【建议
      • 如果还不了解Redis的同学,建议移步(Redis合集

    我们可以将登录功能单独抽取出来,做成一个子系统。

    抽取出来成为子系统

    SSO(登录系统)的逻辑如下:

    // 登录功能(SSO单独的服务)
    @Override
    public TaotaoResult login(String username, String password) throws Exception {
    	
    	//根据用户名查询用户信息
    	TbUserExample example = new TbUserExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andUsernameEqualTo(username);
    	List<TbUser> list = userMapper.selectByExample(example);
    	if (null == list || list.isEmpty()) {
    		return TaotaoResult.build(400, "用户不存在");
    	}
    	//核对密码
    	TbUser user = list.get(0);
    	if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
    		return TaotaoResult.build(400, "密码错误");
    	}
    	//登录成功,把用户信息写入redis
    	//生成一个用户token
    	String token = UUID.randomUUID().toString();
    	jedisCluster.set(USER_TOKEN_KEY + ":" + token, JsonUtils.objectToJson(user));
    	//设置session过期时间
    	jedisCluster.expire(USER_TOKEN_KEY + ":" + token, SESSION_EXPIRE_TIME);
    	return TaotaoResult.ok(token);
    }
    
    

    其他子系统登录时,请求SSO(登录系统)进行登录,将返回的token写到Cookie中,下次访问时则把Cookie带上:

    public TaotaoResult login(String username, String password, 
    		HttpServletRequest request, HttpServletResponse response) {
    	//请求参数
    	Map<String, String> param = new HashMap<>();
    	param.put("username", username);
    	param.put("password", password);
    	//登录处理
    	String stringResult = HttpClientUtil.doPost(REGISTER_USER_URL + USER_LOGIN_URL, param);
    	TaotaoResult result = TaotaoResult.format(stringResult);
    	//登录出错
    	if (result.getStatus() != 200) {
    		return result;
    	}
    	//登录成功后把取token信息,并写入cookie
    	String token = (String) result.getData();
    	//写入cookie
    	CookieUtils.setCookie(request, response, "TT_TOKEN", token);
    	//返回成功
    	return result;
    	
    }
    

    总结:

    • SSO系统生成一个token,并将用户信息存到Redis中,并设置过期时间
    • 其他系统请求SSO系统进行登录,得到SSO返回的token,写到Cookie中
    • 每次请求时,Cookie都会带上,拦截器得到token,判断是否已经登录

    到这里,其实我们会发现其实就两个变化:

    • 将登陆功能抽取为一个系统(SSO),其他系统请求SSO进行登录
    • 本来将用户信息存到Session,现在将用户信息存到Redis

    3.2 Cookie跨域的问题

    上面我们解决了Session不能共享的问题,但其实还有另一个问题。Cookie是不能跨域的

    比如说,我们请求<https://www.google.com/>时,浏览器会自动把google.com的Cookie带过去给google的服务器,而不会把<https://www.baidu.com/>的Cookie带过去给google的服务器。

    这就意味着,由于域名不同,用户向系统A登录后,系统A返回给浏览器的Cookie,用户再请求系统B的时候不会将系统A的Cookie带过去。

    针对Cookie存在跨域问题,有几种解决方案:

    1. 服务端将Cookie写到客户端后,客户端对Cookie进行解析,将Token解析出来,此后请求都把这个Token带上就行了
    2. 多个域名共享Cookie,在写到客户端的时候设置Cookie的domain。
    3. 将Token保存在SessionStroage中(不依赖Cookie就没有跨域的问题了)

    到这里,我们已经可以实现单点登录了。

    3.3 CAS原理

    说到单点登录,就肯定会见到这个名词:CAS (Central Authentication Service),下面说说CAS是怎么搞的。

    如果已经将登录单独抽取成系统出来,我们还能这样玩。现在我们有两个系统,分别是www.java3y.comwww.java4y.com,一个SSOwww.sso.com

    现在我们有三个系统

    首先,用户想要访问系统Awww.java3y.com受限的资源(比如说购物车功能,购物车功能需要登录后才能访问),系统Awww.java3y.com发现用户并没有登录,于是重定向到sso认证中心,并将自己的地址作为参数。请求的地址如下:

    • www.sso.com?service=www.java3y.com

    sso认证中心发现用户未登录,将用户引导至登录页面,用户进行输入用户名和密码进行登录,用户与认证中心建立全局会话(生成一份Token,写到Cookie中,保存在浏览器上)

    4步过程

    随后,认证中心重定向回系统A,并把Token携带过去给系统A,重定向的地址如下:

    • www.java3y.com?token=xxxxxxx

    接着,系统A去sso认证中心验证这个Token是否正确,如果正确,则系统A和用户建立局部会话(创建Session)。到此,系统A和用户已经是登录状态了。

    第五步和第六步

    此时,用户想要访问系统Bwww.java4y.com受限的资源(比如说订单功能,订单功能需要登录后才能访问),系统Bwww.java4y.com发现用户并没有登录,于是重定向到sso认证中心,并将自己的地址作为参数。请求的地址如下:

    • www.sso.com?service=www.java4y.com

    注意,因为之前用户与认证中心www.sso.com已经建立了全局会话(当时已经把Cookie保存到浏览器上了),所以这次系统B重定向到认证中心www.sso.com是可以带上Cookie的。

    认证中心根据带过来的Cookie发现已经与用户建立了全局会话了,认证中心重定向回系统B,并把Token携带过去给系统B,重定向的地址如下:

    • www.java4y.com?token=xxxxxxx

    接着,系统B去sso认证中心验证这个Token是否正确,如果正确,则系统B和用户建立局部会话(创建Session)。到此,系统B和用户已经是登录状态了。

    系统B的流程图

    看到这里,其实SSO认证中心就类似一个中转站

    img

    涵盖Java后端所有知识点的开源项目(已有6 K star):https://github.com/ZhongFuCheng3y/3y

    如果大家想要实时关注我更新的文章以及分享的干货的话,微信搜索Java3y

    PDF文档的内容均为手打,有任何的不懂都可以直接来问我(公众号有我的联系方式)。

    展开全文
  • 初学者学Java常遇到的问题,我都给你回答了!

    千次阅读 多人点赞 2020-02-01 09:58:31
    文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 春节在家刷知乎,看到了一个知乎的问题:《学习Java可以干什么呢?》 我是一个Java的初学者,大概学了四天,对Java到底能做什么...

    前言

    只有光头才能变强。

    文本已收录至我的GitHub精选文章,欢迎Starhttps://github.com/ZhongFuCheng3y/3y

    春节在家刷知乎,看到了一个知乎的问题:《学习Java可以干什么呢?

    我是一个Java的初学者,大概学了四天,对Java到底能做什么还是一头雾水,每天对着黑屏(DOS系统)除了编译还是编译,那么Java对于一个初学者来说Java可以做些什么呢?

    问题的链接:

    看到了这个问题,就想起了我在大学自学的时候有同样的问题,现在工作了,来写写自己的看法,希望对广大的初学者有所帮助。

    注:本文非常适合零基础初学者观看

    如果别人让我介绍我是做什么工作内容的,我可能会用以下的方式告诉他(不知道学Java可以干些什么,可能就不知道下面的流程是怎么样的):

    “你可以掏出手机,打开微信”

    掏出手机,打开微信

    “我们都是玩微信的人,要进入微信先得有个账户,所以要先注册“

    微信注册页面

    “注册实际上就是把你的账号和密码「保存」起来”。

    账号和密码「保存」起来

    “如果你注册成功了,那小本本「数据库」就有你的账号和密码了。等你登录的时候,就去小本本「数据库」查一下你输入的账号和密码是否匹配

    登录

    “看到这里,有没有觉得「程序员」真是容易当,不就把输入的数据记录下小本本,等用到的时候再查一下而已嘛。其实不然,就好比微信的注册页面,拿IOS系统来说,从IOS 6 到现在的IOS 12已经有6个版本了。Iphone手机屏幕的尺寸也一直在变,从3.5英寸到现在的6.5英寸。微信团队需要对不同的「版本」,不同的「屏幕大小」进行兼容,让iPhone4s还是iPhoneXS Max都能用上微信。(起码在不同的手机上,看到的注册功能都是完整的,而不是东一块西一块不整齐的)”

    兼容问题

    “还比如说,小本本「数据库」记下的密码不能是你输入的「原始密码」。举个例子:某一天,一个在微信团队的小伙子拿到了存放账号和密码的小本本「数据库」,把小本本「数据库」的内容给公开了。(或者说一个黑客把微信给攻破了,然后公开小本本「数据库」),那岂不是谁都可以上我的微信号了?”

    公开小本本的内容

    “程序员们当然可以考虑到这点,他们会这样做,将你输入的密码进行「加密」存到小本本「数据库」中。无论是谁,拿到加密后的密码,都**不能「反推」**你原始输入的密码。”

    密码加密

    “所以,每次比对的都是加密后的密码”

    比对的是加密后的密码

    一个功能远远没有上面所讲的那么简单,可能一个小小的功能背后是一个大大的团队在支持…

    收藏等于白嫖,点赞关注才是真情!

    收藏等于白嫖,点赞关注才是真情!

    收藏等于白嫖,点赞关注才是真情!

    我学习Java能做什么?

    题主目前你学了四天有这种情况是非常常见的。我当时学了四天学了什么?

    • 安装Java开发环境用了一天
    • 学习基础的语法:基本的面向对象概念、for循环、if、三目运算符,简单的API(能输出HelloWorld)

    如果题主能继续坚持学习Java基础,发现可能将近一个月都是对着黑窗口在玩。

    • 无论这个黑窗口是系统自带的,还是题主已经在用IDE了

    集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面工具

    学习Java基础的确不能做出些有趣的东西,学着学着会有枯燥的感觉。面向对象-封装继承多态、集合、多线程、反射、网络编程、内部类等等这些Java基础都是在黑窗口上学习和实践的。

    这些玩意有意思吗?是没什么意思,学完这些知识会让自己产生疑问 “这些基础能写成一个应用吗”(无论是现在用的知乎APP还是PC版的知乎)。

    这是一个非常正常的疑问,我在初学的时候也经常问自己:”我学这些东西好像没什么卵用啊,为什么网上(知乎、贴吧等论坛)的都在说 “初学要打好基础等你学好Java基础,那工作就不愁了

    但是我当时一点都不知道这些基础用在哪里,迷茫

    我看视频还是看书?

    题主能够在知乎上提问了,我也默认题主已经在知乎看到过不少类似的问题,可能还没找到自己想要的答案。在搜索的时候应该能看到类似的问题《自学Java看视频还是看书

    这个问题在初学的时候我也经常纠结。纠结的原因很简单:

    • 会有一部分人说:看视频没用,视频讲得太简单了,都是骗你去培训班的。看视频也太慢了,学习最快还是看书好
    • 会有一部分人说:零基础看书看不进去,学不会的,看视频好,一个老师带着你学习

    这个问题我在工作了以后还跟同事讨论过,我是支持零基础学习看视频,他是支持直接看书籍

    我俩谁也说服不了谁。那到底是初学看视频比较好,还是看书籍比较好?

    知识点好多,我记不住

    随便找一本评分比较高的Java基础的书籍来看一下,都是非常的。以《Java疯狂讲义》为例,有889页。拿着他比砖头还要重。

    今天跟着书籍/视频学习了「内部类」,等学到多线程的时候再看一下这个「内部类」,发现已经看不懂他的语法了。昨天跟着书籍/视频学习了「网络编程」,发现上周学完的集合API全忘掉了…

    咋整?知识点这么多,有这么多的API,我不可能全部能记得住啊…学完很容易就忘记了。

    哪些需要重点学习,工作中常用的知识点有哪些

    在初学Java的时候然后去相关的IT论坛逛逛,发现全都看不懂。明明是在学编程,但IT论坛的问题一个都看不懂。看着一大堆的专业名词,就犹如明明是中国人但看不懂奰媕鳏魍谶觳豳这些字一样。

    初学者在论坛上看到面向切面编程、高并发、AOC、IOC、Mybatis、Linux这些可能都不知道是干嘛的,明明是Java的标签,但出来专业名词的好像都看不懂。

    Java要学的东西也太多了吧,基础已经这么多了,后面的怎么学,我应该学习哪些重点啊?

    我学到怎么样的程度可以找到一份工作

    我耗时几个月熬过头了,已经学了Java基础、JavaWeb、简单的数据库、SSM框架等等一些基本的使用了。现在想要找一份工作,但不知道企业招人的标准是什么。

    现在我学得这些,我觉得还有点虚,感觉跟实际工作的内容有较大的差距,学了这么多还是没有一点儿的底气,怎么办?

    会写一点点的SSM和增删改查,简单的会写,难的就不会了**。很急,在线等,怎么办**。

    我的理解

    学习Java能干什么?

    现在Java按简单来说有两种方向:后端和客户端

    • 对造APP感兴趣的可以学Android
    • 对服务端感兴趣的可以学Java后端
    • (后端延伸出去也可以学大数据…

    既然你会在知乎上提问了,你有没有想过你输入完内容,点击发布问题按钮的时候程序员为你做了些什么?

    1. 点击发布问题的时候,至少你提的这个问题是需要能被你再次打开,看看有没有相关回答者的吧?那是不是知乎要拿小本本把你这个问题给记录下来,后续找到了这个问题然后给你下一次打开。
    2. 那至少要做的就得把你发布的问题记录下来(记下),等你再次点开的时候再找到你的问题(查找),如果你把问题给删除了,那就得把记下的问题给删掉(删除),如果你把问题给修改了,那就得把你记下的问题给修改了。总之,你先要把问题给发布(存到小本本里边),你才能删改查
    3. 上面这些工作谁来干?程序员写代码来做。可能用Java,可能用Python,可能用Go,可能用全世界最好的语言PHP…

    扯了一大堆,那我为啥还天天对着黑窗口在学习?而不是直接学习《如何实现类似知乎的发布问题功能》

    显然你读懂一篇英文课文之前,你总得认识单词。你连单词都不认识,怎么做阅读理解呢?学习Java能做很多东西,你日常用到的APP/浏览的网页背后很可能就是用Java写的代码。

    总之,学习Java了可以能让你了解一个网站和APP的基本运行原理,点了一个按钮会发生什么,为什么会这样。

    1. 知道为什么今年淘宝双十一在添加购物车的时候,有时会出现失败
    2. 知道为什么我在查飞机票的时候,查不到信息
    3. 知道为什么…

    看书还是看视频

    我是建议零基础看视频入门的,原因有以下:

    • 大部分零基础学Java的同学都没有比较好的理解能力,看视频可以帮助你快速入门(视频可以加速观看)

    • 避免踩坑。书上讲的知识点的确是非常全,但有两个问题:

      • ①初学者抓不到重点,可能对着细小的知识点猛学一顿,发现这个知识并没多大的卵用。
      • ②初学者不知道学习路线。看书不是完完整整从头看到尾的,很可能书上一段的知识点现在已经没用了,但是你还是费劲去学(比如AWT SWING 现在就用得很少了,但书还是有大篇幅去讲解,如果你顺着学可能就浪费很多时间在里边)

    看视频能让你抓住重点,快速了解知识点。但总的来说是因人而异,有的人理解能力就是好,看书就很快就学会了。

    知识点太多,学完就忘,记不住

    要明确的是,我们写代码的不是背书,不是让你将所有的API给记下来。现在开发工具,提示功能已经是比较好的了。在工作的时候忘了,也可以查百度/Google。

    我们并不需要把所有的东西给记下来,重要的是:我们知道有这项技术,这项技术能帮我们解决掉什么问题

    所以,在学习一项技术之前,必须要知道为什么。为什么需要学习这项技术,不学的话行不行。学了这项技术,我能解决什么问题。

    如果不理解为什么要学习某项技术,就去学用法和API。我认为如果隔一阵子不用,的确是会忘记的。

    比如说,如何你连“为什么要用多线程”你都无法用通俗的话来解释清楚。

    即便你当时学习的时候知道多线程可以用xxx方式来创建,多线程的xxx的api。那再过两个月,人家问你”Java多线程有什么用啊?”。

    你想想你还能答什么,我认为你是记不住“多线程可以用xxx方式来创建、多线程的xxx的api”这些知识点了。

    • 如果你不知道学习某项技术是干嘛用的,那先不要学

    • 如果你不知道学习某项技术是干嘛用的,那先不要学

    • 如果你不知道学习某项技术是干嘛用的,那先不要学

    重点的东西可以写笔记记录下来(这个也是因人而异,我身边的大佬很多也不写笔记。但是我是推崇写笔记的)。

    哪些需要重点学习,工作常用的知识点

    我简单整理了一下画成了思维导图:

    总结一下我认为学习Java的路线:

    • Java基础–>流程控制–>面向对象(包括Java语法)–>Java集合–>Java IO流–>异常–>多线程–>网络编程–>反射
    • JavaWeb基础–>HTML/CSS/JavaScript/jQuery–>Tomcat–>XML/注解->Servlet–>HTTP–>Filter过滤器和监听器–>JSP–>AJAX/JSON–>数据库(MySQL)–>JDBC和DbUtils
    • 项目管理和框架–>Maven–>SpringBoot
    • Linux基本命令

    最后我们的项目是这样的:

    • 以Maven来管理我们的项目
    • 前端通过BootStrap来搭建页面框架
    • SpringBoot来搭建Java后端环境,SpringMVC处理前端请求(SpringBoot整合了)
    • DAO层使用DbUtils组件来完成,MySQL作为数据库

    怎么样才能找到工作

    只要你能从零把一个项目搭建起来,能运行在服务器上。用上的技术还不烂,那我认为就可以找到Java的工作了。

    其实学完上面的,认认真真花一个月从零自己写一个达到找工作的门槛是不难的。但面试之前是一定需要刷面试题的。

    如果还是学生的同学一定一定要参加校招,一定一定要刷算法题,巩固计算机网络、操作系统、数据库的基础。

    如果还是学生的同学一定一定要参加校招,一定一定要刷算法题,巩固计算机网络、操作系统、数据库的基础。

    如果还是学生的同学一定一定要参加校招,一定一定要刷算法题,巩固计算机网络、操作系统、数据库的基础。

    坚持坚持坚持学习就肯定能找到工作!

    最后

    由于篇幅问题,很多细节就没在文章中写了。但是我已经把我自学到找到工作以及工作常用到的技能都写成了博客。现在已经更新了300+多的原创文章。

    从Java基础(集合、多线程、设计模式)到JavaWeb基础(Servlet、JSP、过滤器)再到JavaEE常用框架(SpringMVC、Spring、Mybatis、SpringBoot)再到找工作的经历(写简历,刷面试题)再到工作后常用的技能(Linux命令,SQL编写,经验分享)都记录了下来。文章质量都杠杠的,欢迎查阅

    如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号「Java3y」。

    • 🔥海量视频资源
    • 🔥Java精美脑图
    • 🔥Java学习路线
    • 🔥开发常用工具
    • 🔥精美整理好的PDF电子书

    在公众号下回复「888」即可获取!!

    本已收录至我的GitHub精选文章,欢迎Starhttps://github.com/ZhongFuCheng3y/3y

    求点赞 求关注️ 求分享👥 求留言💬 对我来说真的 非常有用!!!

    收藏等于白嫖,点赞才是真情!

    收藏等于白嫖,点赞才是真情!

    收藏等于白嫖,点赞才是真情!

    展开全文
  • java贪吃蛇源码

    万次阅读 多人点赞 2018-05-20 22:23:50
    java是一种面向对象的语言,有着其中不用质疑的优点。学习java将近三个月了,一直在琢磨着“万物皆对象”的意义,却总是只知其表不知其意,做完这个java贪吃蛇后才有了那么一点的理解。直接上效果图。 游戏分为了...

    欢迎访问我的个人博客 https://jialaner.cn/​​​​​​​

    java是一种面向对象的语言,有着其中不用质疑的优点。学习java将近三个月了,一直在琢磨着“万物皆对象”的意义,却总是只知其表不知其意,做完这个java贪吃蛇后才有了那么一点的理解。直接上效果图。

    游戏分为了六个类,分别为:

    Node类:蛇身都是由一个一个节点组成,所以首先将节点抽象为一个类。

    Snake类:此类是一条蛇抽象出来的一个类。一种包含了存储节点的 LinkedList 类型的集合,蛇的移动的方式是头部加一个节点,尾部减去一个节点。蛇的类有着吃蛋、越界的行为方法。

    SnakeGameView类:这个类是一个游戏界面的类,用于布局游戏的界面。

    GameControl类:此类用于监听键盘,从而实现对游戏的操作。

    GameRunThread类:此类是一个线程类,用于不断重画界面。

    DrawView类:此类继承了面板类,从而拥有了paint()方法的使用权,用于游戏面板的重画,像方格、蛇、蛋、的重画。

    其中存在一个问题,就是游戏在不断的重画过程中,会出现游戏的闪烁问题,就引出了双缓冲的技术。

    在编写程序的时候,总会出现我们意料之外的情况,像游戏变量权限问题、方法归属问题,都需要我们进行思考,如何让我们的程序执行、编写起来更合理、更加符合面向对象编程的思维维,护时改动最少的代码去实现最好的效果,这些都应该是我们去思考的问题。对于游戏的越界问题,一般有两种方式:中心检测法和边界检测法,在这里我用的是边界检测法,具体情况具体选择。

    程序可能有着其他不太合理之处,还请大家原谅一个学java不到三个月的求学者。谢谢大家。下面开始上源码。

    Node类

    public class Node {
    	
    	private int nodeX;
    	private int nodeY;
    	
    	public Node(int nodeX, int nodeY) {
    		
    		this.nodeX = nodeX;
    		this.nodeY = nodeY;
    	}
    	
    	public int getNodeX() {
    		
    		return nodeX; 
    	}
    	public void setNodeX(int nodeX) {
    		
    		this.nodeX = nodeX;
    	}
    	public int getNodeY() {
    		
    		return nodeY;
    	}
    	public void setNodeY(int nodeY) {
    		
    		this.nodeY = nodeY;
    	}
    
    }
    

    Snake类

    public class Snake {
    	
    	private LinkedList<Node> snakeBody;
    	private Random random;
    	//Snake的方向    0上, 1 右 , 2 下 , 3 左
    	private int direction = 0;  
    	
    	private SnakeGameView snakeGameView;
    	
    	public Snake(int snakeHeadX, int snakeHeadY, SnakeGameView snakeGameView) {
    		random = new Random();
    		snakeBody = new LinkedList<>();
    		snakeBody.add(new Node(snakeHeadX, snakeHeadY));
    		this.snakeGameView = snakeGameView;
    	}
    	
    	//获取Snake的方向
    	public int getDirection() {
    		
    		return direction;
    	}
    	//设置Snake方向
    	public void setDirection(int direction) {
    		
    		this.direction = direction;
    	}
    	//获取Snake头部结点
    	public Node getSnakeHead() {
    		
    		return snakeBody.getFirst();
    	}
    	//获取Snake尾部结点
    	public Node getSnakeTail() {
    		
    		return snakeBody.getLast();
    	}
    	//获取Snake的Body
    	public LinkedList<Node> getSnakeBody(){
    		
    		return snakeBody;
    	}
    	//Snake移动
    	public void snakeMove() {
    		
    		switch(direction) {
    		case 0:
    			snakeBody.addFirst(new Node(getSnakeHead().getNodeX() ,getSnakeHead().getNodeY() - DrawView.VIEW_NUMBER));
    			break;
    		case 1:
    			snakeBody.addFirst(new Node(getSnakeHead().getNodeX() + DrawView.VIEW_NUMBER,getSnakeHead().getNodeY()));
    			break;
    		case 2:
    			snakeBody.addFirst(new Node(getSnakeHead().getNodeX(),getSnakeHead().getNodeY()+ DrawView.VIEW_NUMBER));
    			break;
    		case 3:
    			snakeBody.addFirst(new Node(getSnakeHead().getNodeX() - DrawView.VIEW_NUMBER,getSnakeHead().getNodeY()));
    			break;
    		}
    		snakeBody.removeLast();
    	}
    	//Snake 吃Egg
    	public void eatEgg(Node egg) {
    		if(snakeBody.getFirst().getNodeX() == egg.getNodeX() && snakeBody.getFirst().getNodeY() == egg.getNodeY()) {
    		   snakeBody.add(egg);
    		   //产蛋
    		   snakeGameView.setEgg(random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER,
    					random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER);
    		   SnakeGameView.gameScore = SnakeGameView.gameScore + 5;
    		   snakeGameView.getJTextArea().setText(SnakeGameView.gameScore + "");
    		   System.out.println("吃到蛋了");
    		}
    	}
    	//Snake越界
    	public void snakeRunInterface() {
    		
    		if(this.getSnakeHead().getNodeX() < 0 || this.getSnakeHead().getNodeY() < 0||
    				this.getSnakeHead().getNodeX() > (DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER)||
    				this.getSnakeHead().getNodeY() > (DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER)) {
    			SnakeGameView.gameState = false;
    		}
    	}
    }

    SnakeGameView类

    public class SnakeGameView extends Frame{
    		
    	private JLabel jl;
    	private DrawView drawView;
    	private Panel panel;
    	private JLabel scoreTitle;
    	private JLabel score;
    	private Panel rule;
    	private JTextArea hint;
    	
    	private Random random;
    	public static boolean gameState = true;
    	public static int gameScore = 0;
    	private Snake snake;
    	private Node egg;
    	private GameRunThread grt;
    	private static Thread thread;
    	
    	public SnakeGameView() {
    		
    		random = new Random();
    		//初始化Snake
    		snake = new Snake(10 * DrawView.VIEW_NUMBER + random.nextInt(19) * DrawView.VIEW_NUMBER,
    				10 * DrawView.VIEW_NUMBER + random.nextInt(19) * DrawView.VIEW_NUMBER,this);
    		//初始化Egg
    		egg = new Node(random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER,
    				random.nextInt(DrawView.VIEW_WIDTH - 1) * DrawView.VIEW_NUMBER);
    		//初始化画板
    		drawView = new DrawView(snake, egg);
    		grt = new GameRunThread(drawView, snake);
    		thread = new Thread(grt);	
    		
    		jl = new JLabel("SnakeGame-3.0",JLabel.CENTER);	
    		panel = new Panel();
    		scoreTitle = new JLabel("Score", JLabel.CENTER);
    		score = new JLabel(gameScore + "", JLabel.CENTER);
    		rule = new Panel();
    		hint = new JTextArea("    操作方式\n      ↑\n  ←      →\n      ↓\n\n【Esc】退出程序\n\n关于\n");		
    	}
    	
    	//设置鸡蛋
    	public void setEgg(int eggX, int eggY) {
    		
    		this.egg.setNodeX(eggX);
    		this.egg.setNodeY(eggY);
    	}
    	//获得
    	public JLabel getJTextArea() {
    		return score;
    	}
    	//主方法
    	public static void main(String[] args) {
    		
    		new SnakeGameView().showView();
    		thread.start();
    	}
    	public void showView() {
    		
    		jl.setFont(new Font("宋体", 1, 18));//设置字体,0正常,1粗体
    		jl.setForeground(Color.white);//设置颜色
    		jl.setBounds(0, 0, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 70, 40);
    		drawView.setBackground(new Color(51,51,51));
    		drawView.setBounds(20, 50, DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1);
    		panel.setLayout(null);	
    		panel.setBackground(new Color(0,102,102));
    		panel.setBounds(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 40, 50, 150, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER);	
    		scoreTitle.setFont(new Font("宋体", 1, 18));//设置字体,0正常,1粗体
    		scoreTitle.setForeground(Color.white);//设置颜色
    		scoreTitle.setBounds(0, 0, 150, 50);
    		score.setFont(new Font("宋体", 1, 20));//设置字体,0正常,1粗体
    		score.setForeground(Color.white);//设置颜色
    		score.setBounds(0, 50, 150, 40);
    		rule.setBackground(new Color(0,128,128));
    		rule.setBounds(0, 90, 150, 1);
    		hint.setFont(new Font("宋体", 0, 16));//设置字体,0正常,1粗体
    		hint.setBounds(10, 100, 130, 150);
    		hint.setBackground(new Color(0,102,102));
    		
    		panel.add(scoreTitle);
    		panel.add(score);
    		panel.add(rule);
    		panel.add(hint);	
    		this.add(jl);
    		this.setTitle("SnakeGame-3.0");
    		this.setSize(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 210, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 70);
    		this.setLocation(500, 200);
    		this.setLayout(null);
    		//this.setUndecorated(true);
    		this.setBackground(new Color(0,128,128));
    		this.add(drawView);
    		this.add(panel);
    		this.addKeyListener(new GameControl(snake));
    		this.addWindowListener(new WindowAdapter() {
    			public void windowClosing(WindowEvent we) {
    				System.exit(0);
    			}
    		});
    		this.setVisible(true);
    		
    	}
    
    }

    DrawView类

    public class DrawView extends Panel{
    	
    	//画板的宽度高度
    	public static final int VIEW_WIDTH = 40;
    	public static final int VIEW_HEIGHT = 40;
    	public static final int VIEW_NUMBER = 15;
    	private Image iBuffer;  
    	private Graphics gBuffer;  
    	private Snake snake;
    	private Node egg;
    	
    	public DrawView(Snake snake, Node egg) {
    		
    		this.snake = snake;
    		this.egg = egg;
    	}
    	
    	public void paint(Graphics g) {
    		
    		snake.snakeMove();
    		this.drawGridding(g);
    		this.drawSnake(g);
    		this.drawEgg(g);
    		snake.eatEgg(egg);
    		System.out.println("("+snake.getSnakeHead().getNodeX()+","+snake.getSnakeHead().getNodeY()+")");
    	}
    	public void update(Graphics g) {
    	 if(iBuffer==null)  
    	    {  
    	       iBuffer=createImage(DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1);  
    	       gBuffer=iBuffer.getGraphics();  
    	    }  
    	       gBuffer.setColor(getBackground());  
    	       gBuffer.fillRect(0,0,DrawView.VIEW_WIDTH * DrawView.VIEW_NUMBER + 1, DrawView.VIEW_HEIGHT * DrawView.VIEW_NUMBER + 1);  
    	       paint(gBuffer);  
    	       g.drawImage(iBuffer,0,0,this); 
    	}
    	//画网格
    	public void drawGridding(Graphics g) {
    		
    		g.setColor(new Color(128,128,128));
    		for(int i = 0; i < VIEW_WIDTH; i++) {
    			g.drawLine(0, i * VIEW_NUMBER, VIEW_WIDTH * VIEW_NUMBER, i * VIEW_NUMBER);
    		}
    		for(int i = 0; i < VIEW_HEIGHT; i++) {
    			g.drawLine(i * VIEW_NUMBER, 0, i * VIEW_NUMBER, VIEW_WIDTH * VIEW_NUMBER);
    		}
    		
    	}
    	//画Snake
    	public void drawSnake(Graphics g) {
    		
    		for(int i = 0; i < snake.getSnakeBody().size(); i ++) {
    			g.setColor(Color.white);
    			if(i == 0)
    				g.setColor(Color.lightGray);
    			g.fillRect(snake.getSnakeBody().get(i).getNodeX(), snake.getSnakeBody().get(i).getNodeY(), VIEW_NUMBER, VIEW_NUMBER);
    		}
    	}
    	//画Egg
    	public void drawEgg(Graphics g) {
    		
    		g.setColor(Color.yellow);
    		g.fillRect(egg.getNodeX(), egg.getNodeY(), VIEW_NUMBER, VIEW_NUMBER);
    	}
    	
    }

    GameRunThread类

     

    public class GameRunThread implements Runnable{
    
    	private int runTime = 200;
    	private DrawView drawView;
    	private Snake snake;
    	
    	public GameRunThread(DrawView drawView, Snake snake) {
    		this.drawView = drawView;
    		this.snake = snake;
    	}
    
    	public void run() {
    		
    		while(true) {
    			
    			snake.snakeRunInterface();
    			
    			if(SnakeGameView.gameState) {
    				
    				drawView.repaint();
    				
    				try {
    					Thread.sleep(runTime);
    				}catch(InterruptedException e) {
    					e.printStackTrace();
    				}
    					
    			}
    		}
    		
    	}
    
    }
    

    GameControl类

    public class GameControl implements KeyListener{
    
    	private Snake snake;
    	
    	public GameControl(Snake snake) {
    		
    		this.snake = snake;
    	}
    	
    	public void keyReleased(KeyEvent ke) {
    		
    		switch(ke.getKeyCode()) {
    		
    		case KeyEvent.VK_UP:
    			snake.setDirection(0);
    			break;
    		case KeyEvent.VK_RIGHT:
    			snake.setDirection(1);
    			break;
    		case KeyEvent.VK_DOWN:
    			snake.setDirection(2);
    			break;
    		case KeyEvent.VK_LEFT:
    			snake.setDirection(3);
    			break;
    		case KeyEvent.VK_ENTER:
    			
    			if(SnakeGameView.gameState == true) 
    				SnakeGameView.gameState = false;
    			else 
    				SnakeGameView.gameState = true;
    			
    			break;
    		case KeyEvent.VK_ESCAPE:
    			System.exit(0);
    			break;
    		}
    	}
    
    	public void keyPressed(KeyEvent arg0) {}
    	public void keyTyped(KeyEvent arg0) {}
    
    }
    

     

    展开全文
  • 该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址:https://github.com/Snailclimb/JavaGuide. 最近浏览 Github ,收藏了一些还算不错的 Java...

    该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址:https://github.com/Snailclimb/JavaGuide.

    最近浏览 Github ,收藏了一些还算不错的 Java面试/学习相关的仓库,分享给大家,希望对你有帮助。我暂且按照目前的 Star 数量来排序。

    本文由 SnailClimb 整理,如需转载请联系作者。

    1. interviews

    2. JCSprout

    3. JavaGuide

    4. technology-talk

    • Github地址: https://github.com/aalansehaiyang/technology-talk
    • star: 4.2k
    • 介绍: 汇总java生态圈常用技术框架、开源中间件,系统架构、项目管理、经典架构案例、数据库、常用三方库、线上运维等知识。

    5. fullstack-tutorial

    6. java-bible

    • Github地址:https://github.com/biezhi/java-bible

    • star: 1.9k

    • 介绍: 这里记录了一些技术摘要,部分文章来自网络,本项目的目的力求分享精品技术干货,以Java为主。

    • 概览:

       java-bible

    7. EasyJob

    8. advanced-java

    9. 3y

    除了这九个仓库,再推荐几个不错的学习方向的仓库给大家。

    1. Star 数高达 4w+的 CS 笔记-CS-Notes:https://github.com/CyC2018/CS-Notes
    2. 后端(尤其是Java)程序员的 Linux 学习仓库-Linux-Tutorial:https://github.com/judasn/Linux-Tutorial( Star:4.6k)
    3. 两个算法相关的仓库,刷 Leetcode 的小伙伴必备:①awesome-java-leetcode:https://github.com/awangdev/LintCode;②LintCode:https://github.com/awangdev/LintCode

    ThoughtWorks准入职Java工程师。专注Java知识分享!开源 Java 学习指南——JavaGuide(17k+ Star)的作者。公众号多篇文章被各大技术社区转载。公众号后台回复关键字“1”可以领取一份我精选的Java资源哦!

    我的公众号

    展开全文
  • jvm总结

    万次阅读 2019-12-05 09:56:36
    学习JVM的目的也很简单: 能够知道JVM是什么,为我们干了什么,具体是怎么干的。...1.1先来看看简单的Java程序 package cn.myframe.demo; public class D5 { public static void main(String[] args) { ...
  • Java实现蓝桥杯模拟正整数序列的数量

    万次阅读 多人点赞 2020-03-09 12:59:21
     3. 从第三项开始,每一项小于前两项的差的绝对值。  请计算,对于给定的 n,有多少种满足条件的序列。 输入格式  输入一行包含一个整数 n。 输出格式  输出一个整数,表示答案。答案可能很大,请输出答案除以...
  • java对象相等问题

    万次阅读 多人点赞 2019-07-31 19:17:15
    输出结果是true和3,这理解起来很简单,java中对象直接"="赋值其实就是将引用传给对方,让他也指向同一个内存地址。 所以如果a改变了里面属性的值,那这个地址存储的内容就变了,当aa去拿的时候就是变了之后的,...
  • JAVA|Point类

    千次阅读 2019-12-10 00:16:55
    Point类 创建一个Point类,有成员变量x,y,方法getX(),setX(),还有一个构造方...import java.util.Scanner; public class shiyan12 { public static void main(String[] arg){ Point point=new Point(34,46)...
  • JAVA游戏开发-超炫酷贪吃蛇游戏源码及教程

    万次阅读 多人点赞 2019-08-29 17:28:49
    自己刚好正在学习JAVA编程,也想实现一个类似功能的游戏Demo练手,在网上查看了不少源码案例,全都是很古老的方块式贪吃蛇游戏案例,没有想要的实现,因此自己动手实现一个JAVA版的贪吃蛇游戏。 我在这个Dome完成...
  • #/*定义一个点类Point,包含2个成员变量x、y分别表示x和y坐标,2个构造器Point()和Point(int x0,y0), 以及一个movePoint(int dx,int dy)方法实现点的位置移动,创建两个Point对象p1、p2, 分别调用movePoint方法后...
  • 输入三个整数x,y,z,请把这三个数由小到大输出。 实现代码: 第1种方法: import java.util.Scanner; public class xyzMaxMin{ public static void main(String[] args) { Scanner sc = new Scanner...
  • JAVA 的++y(--y)和y++(y--) 用法

    千次阅读 2019-04-17 16:10:39
    JAVA 的++y(–y)和y++(y–) 用法 今天要讲的是JAVA运算符,想必大家都知道运算符是什么,最简单的无非就是加、减、乘、除(+、-、*、%),但我要讲的是运算符当中的++y(­­y)和y++(y­­)的应用方法,来看一下。...
  • Java实现表白小程序

    万次阅读 多人点赞 2016-12-05 17:29:25
    今天闲来无事,教大家一个哄妹子的小case。我们需要创建一个心形图案,按照心形图案的位置和长度,对所创建的字符串进行截断并在所...import java.awt.*; import javax.swing.JFrame; public class Cardioid extends
  • 看完这篇JVM,阿里面试官都不怕!看完就能拿offer

    万次阅读 多人点赞 2020-02-18 18:48:35
    就是让JVM创建一个Java3y对象,但是这时候方法区中没有Java3y类的信息,所以JVM马上加载Java3y类,把Java3y类的类型信息放到方法区中(元空间) 4、加载完Java3y类之后,Java虚拟机做的第一件事情就是在堆区中为一个新...
  • Java程序员花两天做了个消消乐(天天爱消除)

    万次阅读 多人点赞 2021-06-21 09:33:17
    引言: 一直就想做一个消消乐,这次正好找到了素材,就自己琢磨写了一个,我觉得这个游戏难点就在消除后的下落。...为了帮助更多小白从零进阶 Java 工程师,从CSDN官方那边搞来了一套 《Java 工程师学习成长知识图谱
  • java学生成绩管理系统

    万次阅读 多人点赞 2016-04-12 14:33:51
    *@name:java学生成绩管理系统. *@功能:学生相关信息,录入,查询,统计,修改等.... *@PS:图形界面的学生管理系统不要求就不做了. */ import java.util.Scanner; import java.lang.*; import ja
  • RSA加密与解密(Java实现)

    万次阅读 多人点赞 2018-10-17 10:22:52
    随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCG77PYUAcCpANyUmsHJfuDIia9FcITsuu9lnfbE2BbEwd4SOxPBFTwEWTZ9/e+mtjP97KFEBohGkwy+VHE5KocypBv0O7YgEevwMgpvxyYY0v104CB/k0yjCFV7lc7FxY5VgEKrMiXTIkMr1...
  • 面试篇:Java 实现 x 的 y 次方

    千次阅读 2018-04-26 09:28:50
    前两天面试的一道题,记录一下: Guava 中的实现: /** * Returns {@code b} to the {@code k}th power. Even if the result overflows, it ... System.out.println(Power.pow(3,100)); return ; } } 关键还是算法
  • 我大学的时候应该要这样:学习Java集合

    千次阅读 多人点赞 2019-12-05 13:36:14
    (微信搜Java3y即可关注) Java精美脑图 Java学习路线 Java常用的开发工具 原创PDF电子书 PDF文档的内容均为手打,有任何的不懂都可以直接来问我(公众号有我的联系方式)。 在公众号下回复「888」即可获取!!
  • java数组的排序

    万次阅读 多人点赞 2019-05-15 21:00:57
    互换后的第1与第3比,如果第1比第3大,位置互换, 一直到最后,最小值在第1位。第二次循环时第一位不参与 也就是内循环结束一次,最小值出现头角标位置上。 代码; 1. import java.util.*; 2. ...
  • java中x^=y^=x^=y交换整形数据Bug

    千次阅读 2018-04-19 17:17:24
    但是如果想在java中这么做,那就哈哈哈哈~ 让我们直接看一下这么做的后果: 瞧见了没,y是变成1了,但是x却并不等于2,而是等于0。 首先我们来解析一下,如果通过异或来交换两个整数,其正确流程如下: x = ...
  • 1.设计一个名为Point的类,表示一个带x坐标和y坐标的点。该类包括: 两个带get方法的数据域x和y分别表示它们的坐标。 一个创建点(0,0)的无参构造方法。 一个创建特定坐标点的构造方法。 一个名为distance的方法,...
  • Java中x+=y和x=x+y两种实现的区别

    千次阅读 2019-03-24 00:44:21
    Java中x+=y和x=x+y两种实现的区别 先看下边两段代码,各有什么错? 例一: short s1 = 1; s1 = s1 + 1; 例二: short s1 = 1; s1 += 1; 第一段代码无法通过编译,由于 s1+1 在运算时会自动提升表达式的...
  • 文章目录一、填空题二、判断题三、选择题四、简答题五、编程题六、原题及其解析 一、填空题 1.true和false 2.... 3....1、Java语言的八种基本数据类型有:byte字节型,占一个字节。short短整型,占两
  • Java小游戏坦克大战(一)

    千次阅读 多人点赞 2018-07-15 20:15:54
    最近,学校安排来深圳尚学堂实训,我又重新拿起了我的Java,故此更新一个月的Java实训,今天主要是一个Java小游戏--坦克大战的坦克的移动的简单实现。(20180715) 1、首先,我们建立一个com.hbust.app的包,继续...
  • java简易小游戏

    万次阅读 多人点赞 2021-04-05 13:22:43
    java简易小游戏制作 游戏思路:设置人物移动,游戏规则,积分系统,随机移动的怪物,游戏胜负判定,定时器。 游戏内容部分 package 代码部分; import javax.swing.*; import java.awt.*; import java.awt.event....
  • java 练手小项目

    千次阅读 多人点赞 2018-03-29 20:45:28
    学习了javaSE的基础,为了巩固对Java面向对象编程,以及java多线程编程的理解,使用swing 写了一个很简单的小项目,源码github地址: https://github.com/pythondever/swing-demo 喜欢的同学可以学习学习 整体...
  • //打印二维码 TscLibDll.INSTANCE.setup("20", "20", "3", "10", "0", "3", "0"); TscLibDll.INSTANCE.clearbuffer();// 清除缓冲信息 TscLibDll.INSTANCE.sendcommand("GAP 2 mm,0");// 设置 打印的方向. ...
  • include<stdio.h> int main() { /*。...输出对应的象限,用数字1,2,3,4分别对应四个象限。> */ int x,y; scanf("%d%d",&x,&y); if(x > 0) { if(y > 0) { printf(“1”); } ...
  • java实现飞机大战小游戏(源码+注释)

    万次阅读 多人点赞 2021-04-24 14:49:37
    工程文件二.Main.java三.GameFrame.java四.GamePanel.java五.FlyObject六.Hero.java七.Ep.java八.Fire.java九.App.java十.效果演示![在这里插入图片描述]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 804,401
精华内容 321,760
关键字:

java3y

java 订阅