博客系统实现

一.准备工作

1.创建项目,把前端写好的博客静态页面拷贝到webapp目录中

2.引入依赖,这里主要用到servlet,mysql5.1.47,jacson2.15.0

3.找到右上角的edit configurations->smartTomcat->进行配置

4.数据库设计:设计对应的表结构,并把数据库相关代码进行封装。如何设计表结构?首先确定实体,其次确认实体之间的关系。这里的实体就是博客和用户,所以就是一个blog表,一个user表。两者是一对多的关系->一个博客只能属于一个用户,然而一个用户可以拥有多篇博客。所以应在博客表中引入userid。

1.对数据库的操作

先把数据库创建好,并创建好表,为了方便创建,先在webapp下面新建一个文件db.sql,然后再这里面把sql语句编辑好,然后复制粘贴到MySQL中。这样方便修改语法错误(其实直接在MySQL中创建也可以)

然后我们把对数据库进行操作的代码进行封装。我们将对数据库的操作都放到model包中。所以在java目录下新建一个model包

建立连接等通用操作

然后再在model包中新建一个DButil类,用来封装数据库建立连接的代码。这是由于接下来的代码中有很多个servlet都需要使用库,所以就需要有单独的地方把DataSourse的操作进行封装,而不是只放到某个servlet的init中

public class DButil {
    private static DataSource ds=null;
    private static DataSource getDataSourse(){
        if(ds==null){
            ds=new MysqlDataSource();
            ((MysqlDataSource)ds).setUrl("jdbc:mysql//127.0.0.1:3306/blog_system?charset=utf8&useSSL=false");
            ((MysqlDataSource)ds).setUser("root");
            ((MysqlDataSource)ds).setPassword("20050430zyh");
        }
        return ds;
    }
    public Connection getConnection() throws SQLException {
        return getDataSourse().getConnection();
    }
    public static void close(ResultSet resultSet, PreparedStatement statement,Connection connection){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

如上,对外只开放建立连接和关闭的操作,建立数据源的操作直接封装起来

两个类表示两张表

每个表都需要专门搞一个类来表示

public class Blog {
    private int blogid;
    private String content;
    private Timestamp postTime;
    private int userid;

    public int getBlogid() {
        return blogid;
    }

    public void setBlogid(int blogid) {
        this.blogid = blogid;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Timestamp getPostTime() {
        return postTime;
    }

    public void setPostTime(Timestamp postTime) {
        this.postTime = postTime;
    }

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    @Override
    public String toString() {
        return "Blog{" +
                "blogid=" + blogid +
                ", content='" + content + '\'' +
                ", postTime=" + postTime +
                ", userid=" + userid +
                '}';
    }
}
public class User {
    private int userid;
    private String username;
    private String password;

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                '}';
    }
}

两个类完成对两张表的操作

就用BlogDao和UserDao来命名。Dao,就是Data Access Object(数据访问对象)通过这两个类的对象完成对数据的操作

public class BlogDao {
    //新增,提交博客
    public void insert(Blog blog){
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //建立连接
            connection=DButil.getConnection();
            //构造sql语句
            String sql="insert into blog values (null,?,?,now(),?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,blog.getTitle());
            statement.setString(2,blog.getContent());
            statement.setString(3,""+blog.getUserid());
            //执行sql
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(null,statement,connection);
        }
    }
    //查询博客列表(博客列表页),把库中所有博客都拿到
    public List<Blog> getBlogs(){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        List<Blog> blogList=new ArrayList<>();
        try {
            connection=DButil.getConnection();
            String sql="select * from blog";
            statement=connection.prepareStatement(sql);
            resultSet=statement.executeQuery();
            while(resultSet.next()){
                Blog blog=new Blog();
                blog.setBlogid(resultSet.getInt("blogid"));
                blog.setTitle(resultSet.getString("title"));
                String content=resultSet.getString("content");
                if(content.length()>100){
                    content=content.substring(100);
                }
                blog.setContent(content);
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                blog.setUserid(resultSet.getInt("userid"));
                blogList.add(blog);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(resultSet,statement,connection);
        }
        return blogList;
    }
    //根据博客id查询指定博客
    public Blog getBlog(int blogid){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        Blog blog=new Blog();
        try {
            connection=DButil.getConnection();
            String sql="select * from blog where blogid=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,blogid);
            resultSet=statement.executeQuery();
            if(resultSet.next()){
                blog.setBlogid(resultSet.getInt("blogid"));
                blog.setTitle(resultSet.getString("title"));
                blog.setContent(resultSet.getString("content"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                blog.setUserid(resultSet.getInt("userid"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(resultSet,statement,connection);
        }
        return blog;
    }
    //根据博客id删除指定博客
    public void deleteBlog(int blogid){
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection=DButil.getConnection();
            String sql="delete from blog where blogid=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,blogid);
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(null,statement,connection);
        }
    }
}

注意,在getBlogs这个方法中,获取正文时,不要把全部正文内容都拿出来显示到列表页上,只需要拿出一部分即可,所以会有一个截断操作

在getBlog操作中,由于blogid时主键,所以只能查询到一篇博客,所以不需要while循环,只需要一个if判断,同时,正文不用截断!!!

public class UserDao {
    //根据userid查询对应用户信息(获取用户信息)
    public User getUserByid(int userid){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        User user=new User();
        try {
            connection=DButil.getConnection();
            String sql="select * from user where userid=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,userid);
            resultSet=statement.executeQuery();
            if(resultSet.next()){
                user.setUserid(resultSet.getInt("userid"));
                user.setUsername(resultSet.getString("usernsme"));
                user.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(resultSet,statement,connection);
        }
        return user;
    }
    //根据usernsme查询对应用户信息
    public User getUserByname(String username){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        User user=new User();
        try {
            connection=DButil.getConnection();
            String sql="select * from user where userid=?";
            statement=connection.prepareStatement(sql);
            statement.setString(1,username);
            resultSet=statement.executeQuery();
            if(resultSet.next()){
                user.setUserid(resultSet.getInt("userid"));
                user.setUsername(resultSet.getString("usernsme"));
                user.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DButil.close(resultSet,statement,connection);
        }
        return user;
    }
}

上面这两方法就都很相似。

二.前后端交互,实现博客功能

1.获取博客列表页

在博客列表页加载时,通过ajax方式给服务器发送请求,从服务器数据库中拿到数据显示到页面上

约定前后端交互接口

请求

GET /blog

响应

HTTP/1.1 200 OK

Content-Type:application/json

[

     {

         blogid:1

         title:' '

         content:

         postTime:

         userid:

      }

……

]

让浏览器给服务器发送请求

我们要对前端的blog_list.html使用ajax进行修改,所以首先要引入jquery库:也就是在head标签内加一个script标签:<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

编写前把写死的那部分标签给注释掉,然后在</body>上方进行代码编写,加一个<script>标签,在开始和结束标签之间进行编写:

我们直接将代码封装到函数中,但一定要记住调用!!

服务器处理请求

我们将所有服务器的代码都放到一个包里面,也就是servlet包,然后在改包中线新建一个BlogServlet类。由于对于博客列表页发送的请求的处理方式是要将表中数据按照json格式字符串返回,所以肯定要用到jackson,所以要定义一个成员变量ObjectMapper,最终代码如下:

让前端代码处理响应

这里的关键是根据服务器返回的博客信息去构造博客列表页!!我们使用的是比较朴素的方式来构造博客列表页,也就是基于dom api。dom api是浏览器提供的标准的api,不属于任何第三方库/框架。

如上,我们要构建出类似于这样结构的标签,这些标签有着包含关系以及并列关系,最大的标签是containner-right,其他所有标签都是在它里面。它里面就是一个一个博客,其中每个博客标签里面又并列包含了标题,发布时间,摘要,查看全文按钮

如上。由于在像一个中设置了正文格式为json,所以当把响应返回给客户端后,body部分就自动被解析成了一个json对象,这里由于响应是一个对象列表转化成的json字符串数组,所以是被解析成了json对象数组,所以要通过for循环遍历数组,拿出每一个blog对象进行遍历。

其中,在创建查看全文按钮时,我们的目的是创建一个类似于”查看全文>>"这样的标签,但是大于号要想在html中写出,就必须使用转义字符&gt;小于号就是&lt。因为html标签就是<>构成的。

其次,一点击查看全文,就要进入博客详情页,所以要用到超链接标签,也就是a标签。其中的href属性就是在描述点击后会跳转到哪个页面。同时,点击a标签就会自动发送一个get请求!!!之前我们提到过。

解决出现的问题

到这里,博客列表页就构造完了。我们来测试一下,发现几个问题:1.时间显示不对,现在显示的是时间戳,但我们希望是某年某月某日几点。2.返回的数据的顺序问题,正常来说,最上面的博客应该是最新的博客,但是我们现在再插入一篇博客后,它会被显示到博客列表页的最下面,而不是最上面。

解决时间问题

抓包观察是哪里出现了问题,仔细观察发现在获取博客数据的响应中的postTime就是时间戳。所以是resp.getWriter().write(respJson)出问题了。所以关键就是respJson,它是怎么获取到的呢?

1.首先jackson发现,blogList是一个list,于是就循环遍历了

2.它针对每一个元素(Blog对象)通过反射的方式获取到属性名字,然后再用get方法拿到属性的值。

所以关键就在于修改postTime的get方法,如下:

java标准库中提供了SimpleDateFormet类,来完成时间戳到格式化时间的转化。此类的使用很复杂,不需要背,每次使用前都查一下就行。创建SDF对象,传入指定字符串,用来描述当前时间日期的具体格式,然后使用format方法,里面的参数可以是时间戳,也可以是date对象

解决顺序问题

我们是到,数据库查询到结果的顺序其实是随机的,所以要想固定顺序,就要使用orderby关键字,并按照发布时间降序排列,如下选中部分。

2.获取博客详情页

这个就是在点击查看全文后,就会发送get请求并跳转到了博客详情页(这是我们刚刚编写的a标签实现的逻辑),那我们现在要实现的就是根据请求中的blogid去查询到对应的博客并返回给前端

约定前后端交互接口

请求

GET /blog?blogid=1

响应

HTTP/1.1 200 OK

Content-Type:application/json

{

      blogid:1

      title:

      content:

      postTime:

      userid:

}

前端使用ajax发起请求

打开blog_list.html,在</div>下面添加script标签,进行代码编写:

url中的blogid是如何得到的呢?这里就是用location.search来拿到当前页面的url中的queryString(因为在设置a标签时,其中的href属性中就带有?blogid=……)。(在浏览器中,ctrl+shift+i就可以打开控制台,输入location.search就可以看到当前页面的queryString语句)注意,location.search拿到的是整个query String语句,包括了问号!!

服务器处理上述请求

上面请求的路径还是blog,所以还是在BlogServlet中处理get方法。但是在获取博客列表页的时候已经写了一个doGet方法了呀,这该怎么办?找两者的不同,发现上面的请求时没有blogid的,而当前这个请求是有blogid的。这就是区别。所以进行如下编辑:

前端将响应数据构造成html片段

首先把containner-right里面的内容给注释掉

然后按这个格式去构造片段:

测试一下,发现了两个问题:

1.写完代码之后,会发现点击某个博客,有点博客详情页里还是那些注释掉的内容。这个问题是浏览器缓存引起的。浏览器在加载页面时,是通过网络获取资源的,但是网络速度很慢,所以浏览器会把已经加载是页面在本地硬盘中保存一份,后续再次访问同一个页面时,就不通过网络加载,而是直接加载本地硬盘中的这一份。那这如何克服呢?前端有专业的解决方案,不过咱们不用关心,只需要ctrl+F5刷新一下即可。

当前的详情页,虽然能够显示正文了,但是显示的正文是markdown的原始数据。正常应该显示md渲染后的效果。这就需要通过引入第三方库来完成:

引入依赖:在blog_editor.html的</head>前面粘贴

然后在刚才的构造页面正文的代码进行修改:

这个editormd是editor.md官方文档上提供的一个全局变量。此方法的第一个参数必须是一个标签的id,但是content标签没有设置id,所以我们要在上面的content标签内部加上一个id属性。第二个参数就是一个js对象:

最终这个函数的效果就是把blog.content这里的原始md数据渲染成html放到content div的内容中

3.实现登录

在login.html点击登陆后,应该给服务器发起一个http请求。服务器处理上述请求,读取用户名和密码,在库中查询匹配,若正确,则成功登录,创建会话,跳转到博客列表页(所以登陆成功就直接进行重定向跳转

约定前后端交互接口

请求

POST /login

Content-Type:application/x-www-form-urlencoded

username= &password=

响应

HTTP/1.1 302

Location:blog_list.html

注意,若使用ajax发送请求,就要再写代码完成跳转;但是使用form表单的话,只要提交成功,就可以直接使用302完成页面跳转

前端发送请求

打开login.html,对下面的代码进行逻辑修改:

修改完就是:

服务器处理请求返回响应

先将请求中的用户名和密码获取到,判断是否为空。然后根据用户名去获取对应的用户,要是没获取到,就说明用户名错误了,若获取到,就说明用户名是对的。然后拿着刚刚获取到的用户的密码和请求中的密码对照一下,要是不一致,就说明密码填错了(不过,不管是密码写错买时用户名写错,我们都统一提示用户名或密码不正确)。最后创建会话,还是参数是true,并且设置会话中的属性user就是user对象。

4.强制要求登录

这个功能就是在博客的列表页,详情页,编辑页去判定当前用户是否已经登陆。若未登录,就强制要求跳转到登录页。所以要在这几个页面中,在页面加载时,给服务器发送ajax请求,从服务器获取到一个登录状态即可

约定前后端交互接口

请求

GET /login

响应

HTTP/1.1 200 OK ->表示成功登录

HTTP/1.1 403       ->表示登录失败

响应的格式可以有很多种,比如返回的都是200,但是正文不一样

前端发起ajax请求

打开blog_list.html,在function getBlogs()下面再写一个方法:

这里success是在返回2开头的状态码时会执行,error则是在返回除2以外的数字开头的状态码就hi执行。location.assign就是强制要求跳转到login.html,这是前端页面跳转的方式。那为啥不待会儿在服务器直接返回个302,直接跳转到登录页呢?因为302这样的响应回到ajax中的error中后,无法被ajax直接处理。除非通过提交form表单或者点击a标签这种触发的http请求,浏览器才可以直接跳转。

处理响应的过程比较简单,所以一起写了

服务器处理请求

注意,未登录状态的判定不单单是看会话是否存在,还有看该会话中是否存放着user(为什么?待会实现退出登录的时候就知道了)

测试一下:直接打开列表页,在列表页刷新一下,就发现跳转到了登录页。

但有个问题,虽然已经登陆了,但是一旦重启服务器,就会被判定为未登录状态。因为登陆状态是根据服务器的内存中的session确定的,重启服务器意味着之前的内存要释放。其实这一设定并不科学,如何解决?以后再说。

现在,博客编辑页和详情页也要执行上述逻辑,所以在vscode中创建一个新目录js,js中创建新文件app.js,将getLoginStqatus函数复制过去。

然后在每个页面的<script>上再来个<script src="js/app.js"></script>,然后在下面的script中调用getLoginStatus即可:

这就是把一些公共的js代码单独提取出来放到某个.js文件中,然后通过html中的script标签来引用这些文件内容,此时就可以在html中调用对应的公共代码了。

5.显示用户信息

在列表页显示当前登录的用户的信息,在详情页显示作者信息。在页面加载时,给服务器发送ajax请求,服务器返回对应的用户信息

约定前后端交互接口

请求

GET /userinfo(详情页则是authorid)

响应

HTTP/1.1 200 OK

Type:application/json

{

        userid:

        username:

}

前端发起ajax请求

这是博客列表页

这是博客详情页,通过location.search查到对应的博客id,从而查找对应的作者

服务器处理上述请求

首先是针对博客列表页的。最终要将user对象转成json格式的字符串,所以要有一个ObjectMapper。然后,先取出会话,看看会话是否为空,或者会话中是否存储了user,要是没有,就说明未登录,反之就是已经登录了。最后,在显示用户信息时,为保证安全,就应该将密码置为空!!

最后就是处理博客详情页的请求,首先看看请求中是否带有blogid,要不然没法查询。然后就是根据blogid查到对应的博客。再根据博客找到作者,最后返回作者信息

前端将响应构造成html片段

首先是列表页:

应该将用户名显示到<h3>标签处,所以代码如下:

注意,h3标签没有class属性,所以前面不用加点。

然后是详情页,也是要设置到h3标签:

6.注销/退出登录

在博客列表页/编辑页/详情页都有注销按钮,这就是一个a标签,其中有一个href属性,点击就能够触发一个http请求,就能引起浏览器跳转到另一个页面。

我们现在要做的就是修改a标签,让用户一点击它,就能触发一个http请求,服务器收到了就会把会话中的这个user删除掉并跳转到登录页。(那为啥不直接把会话给删除呢?因为servlet没有提供删除会话的操作!!!不过也可以给会话设置一个过期时间,但是不够优雅。session提供了removeAttribute的方法)

约定前后端交互接口

请求

GET /logout

响应

HTTP/1.1 302

location:login.html

前端发起请求

不用写ajax,直接给a标签添加一个href属性即可

服务器处理请求

7.发布博客

输入标题,正文,期望一点击提交就能够发到服务器这边进行保存

约定前后端交互接口

请求

POST /blog

content-Type:application/x-www-form-urlencoded

title= &content=

响应

HTTP/1.1 302

location:blog_list.html

前端发起请求

就是修改这一块,变成:

也就是给title标签加上name属性。那么如何给正文加上name属性?就是在 <div id="editor">这个标签下加上<textarea name="content" style="display:none"></textarea>,textarea就是一个多行编辑器容器,就把name属性加到它上面即可,然后在初始化editormd对象时加上一个对应的属性即可,也就是在下面的图片中的var editor 中加一个属性saveHTMLToTextarea并赋值为true:

上面这个图片修改为:

表示会把用户在编辑器里面的内容自动保存到textarea中,这样,一点提交,就会在form表单中有拷贝

服务器处理请求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【经典算法】LeetCode 5: 最长回文子串(Java/C/Python3实现含注释说明,Medium)

目录 题目描述思路及实现方式一&#xff1a;动态规划法思路代码实现Java版本C语言版本Python3版本 复杂度分析 方式二&#xff1a;中心扩展法思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相似题目 标签(题目类型)&#xff1a;回文串、动态规划 题目描述 给定一…

【C++】unordered 系列关联式容器

文章目录 1. unordered 系列关联式容器2. unordered_map2.1 unordered_map 的文档介绍2.2 unordered_map 的接口说明 3. unordered_set4. 在线 OJ 1. unordered 系列关联式容器 在 C 98 中&#xff0c;STL 提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可…

吴恩达AndrewNg 关于Agent工作流的分享

主要观点 &#x1f393; 基于HumanEval的测试,使用智能体工作流确实能够显著提升大语言模型的表现,有时甚至超过下一代更强大的模型。&#x1f504; AI智能体设计包括四种模式&#xff1a;反思、工具使用、规划、多智能体协作。&#x1f3d7;️ 快速token生成对于提高AI智能体…

智慧公厕是智慧城市建设中不可或缺的一部分

智慧城市的数字化转型正在取得显著成效&#xff0c;各项基础设施的建设也在迅速发展&#xff0c;其中智慧公厕成为了智慧城市体系中不可或缺的一部分。作为社会生活中必要的设施&#xff0c;公共厕所的信息化、数字化、智慧化升级转型能够实现全区域公共厕所管理的横向打通和纵…

第12章 集合框架

一 集合框架概述 1.1 生活中的容器 1.2 数组的特点与弊端 一方面&#xff0c;面向对象语言对事物的体现都是以对象的形式&#xff0c;为了方便对多个对象的操作&#xff0c;就要对对象进行存储。另一方面&#xff0c;使用数组存储对象方面具有一些弊端&#xff0c;而Java 集合…

设计模式 -- 发布订阅模式

发布订阅模式&#xff1a; 订阅者把自己想订阅的事件注册到调度中心&#xff0c;当发布者发布该事件到调度中心&#xff0c;也就是该事件触发时&#xff0c;由调度者统一调度订阅者注册到调度中心的处理代码。 在javaScript 中我们一般使用事件模型来代替传统的发布订阅模式。 …

一文搞懂路由器2.4G和5G的区别,以及双频合一模式

我们知道&#xff0c;无线路由器是平时生活和工作中最常见不过的一个无线设备&#xff0c;通过它我们的手机、笔记本、智能电视、摄像头等&#xff0c;都可以接入互联网。 其实WiFi在1998年就开始使用了&#xff0c;当时仅仅是在欧美地区小范围使用&#xff0c;我们国家在2008年…

关于Ansible模块 ④

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》与《关于Ansible的模块 ③》之后&#xff0c;继续学习ansible常用模块之…

C++流程控制语句:嵌套循环案例分析【九九乘法表】

在C编程中&#xff0c;循环语句的嵌套是一种常见且强大的技术手段&#xff0c;它允许我们将多个循环结构相互嵌套&#xff0c;形成多维循环。不论是for循环、while循环还是do…while循环&#xff0c;均可以进行嵌套。 而在实践中&#xff0c;由于for循环具有明确的循环变量初…

[法规规划|数据概念]数据要素市场三月速递

“ 代表关注&#xff0c;市场活跃&#xff0c;发展迅速” 01—听听两会代表怎么说 在2024年的全国两会期间&#xff0c;数据要素作为新型的生产要素受到广泛关注&#xff0c;众多代表围绕数据要素市场化、立法、安全监管、人才培养及基础设施建设等方面&#xff0c;积极建言献策…

基于centos7安装docker+k8s+KubeSphere

实验环境&#xff1a;&#xff08;每个服务器推荐内存为8G&#xff09; 服务器 ip地址 主机名 centos7 192.168.80.1…

模型量化——NVIDIA——方案选择(PTQ、 partialPTQ、 QAT)

PTQ、 partialPTQ、 QAT 选择流程 PTQ、 partialPTQ、 QAT 咨询NVIDIA 官方后&#xff0c;他们的校正过程一致&#xff0c;支持的量化算子本质是一样的&#xff0c;那么如果你的算子不是如下几类&#xff0c;那么需要自己编写算子。参考TensorRT/tools/pytorch-quantization/py…

数据库入门-----SQL基础知识

目录 &#x1f4d6;前言&#xff1a; &#x1f4d1;SQL概述&&通用语法&#xff1a; &#x1f433;DDL&#xff1a; &#x1f43b;操作数据库&#xff1a; &#x1f41e;数据类型&#xff1a; &#x1f989;操作表&#xff1a; &#x1f9a6;DML: 语法规则&#x…

helm与k8基础

文章目录 一、helm二、K8S/K3S1.K8S基本组件1.1 资源对象1.2 核心组件1.3典型的创建 Pod 的流程1.4 Kubernetes 多组件之间的通信原理 三、容器运行时 Containerd1.查看当前k3s使用的容器运行时CRI2.K3S修改docker为运行环境3. Containerd 参考 一、helm Helm是Kubernetes的包…

吴恩达机器学习理论基础解读—线性模型(单一特征拟合)

吴恩达机器学习理论基础——线性模型 机器学习最常见的形式监督学习&#xff0c;无监督学习 线性回归模型概述 应用场景一&#xff1a;根据房屋大小预测房价 应用场景二&#xff1a;分类算法&#xff08;猫狗分类&#xff09; 核心概念&#xff1a;将训练模型的数据称为数…

使用C语言函数对数组进行操作

前言 在我们了解数组和函数之后&#xff0c;我们对数组和函数进行结合&#xff0c;之后完成一些操作吧 题目描述 杰克想将函数与数组结合进行一些操作&#xff0c;以下是他想要达到的效果&#xff0c;请你帮帮他吧&#xff01; 创建一个整型数组&#xff0c;完成对数组的操作 1…

Taro框架中的H5 模板基本搭建

1.H5 模板框架的搭建 一个h5 的基本框架的搭建 基础template 阿乐/H5 Taro 的基础模板

人民网至顶科技:《开启智能新时代:2024中国AI大模型产业发展报告发布》

​3月26日&#xff0c;人民网财经研究院与至顶科技联合发布《开启智能新时代&#xff1a;2024年中国AI大模型产业发展报告》。该报告针对AI大模型产业发展背景、产业发展现状、典型案例、挑战及未来趋势等方面进行了系统全面的梳理&#xff0c;为政府部门、行业从业者以及社会公…

推荐一款自动化测试神器---Katalon Studio

Katalon Studio介绍 Katalon Studio 是一款在网页应用、移动和网页服务方面功能强大的自动化测试解决方案。基于 Selenium 和 Appium框架&#xff0c;Katalon Studio集成了这些框架在软件自动化方面的优点。这个工具支持不同层次的测试技能集。非程序员也可以快速上手一个自动…

5分钟了解清楚【osgb】格式的倾斜摄影数据metadata.xml有几种规范

数据格式同样都是osgb&#xff0c;不同软件生产的&#xff0c;建模是参数不一样&#xff0c;还是有很大区别的。尤其在应用阶段。 本文从建模软件、数据组织结构、metadata.xml&#xff08;投影信息&#xff09;、应用几个方面进行了经验性总结。不论您是初步开始建模&#xf…